when I compile the below code in Rust 0.12.0, I get the following error:
error: borrowed value does not live long enough
let _ = match re.captures(a_line.unwrap(
The short answer is, no, you can't just 'extend' the lifetime of a variable like this.
This is a game of connect the types:
Iterator<IoResult<String>>
.a_line
is an IoResult<String> = Result<String, IoError>
, and so .unwrap returns a String
'a
lifetime on the references, statically restricted to only be usable while the String
exists avoiding the problem of dangling references and use-after-free in C++ (for more about String
vs. &str
: this answer & the strings guide).&str
with some lifetime (the 't
) and tries to return a Captures that lasts that long. In this case, the lifetime of the &str
is the lifetime of the String
out of a_line
, and so c
is a Captures
storing data that is only valid this long.&str
with the 't
lifetime of the data that the Captures
is storing, that is, the returned &str
is only guaranteed to last as long as the original &str
fed into captures
(which can't be longer than how long the original String
exists, since that's managing the text in memory)Hence, c1
only lasts for as long as the String
from a_line
, and that String
is scoped inside the loop, that is, each time you step through the loop, you get a new String
which is deallocated at the end. If the compiler let it escape by allowing it to be placed in vect1
, the code would be prone to use-after-free/dangling reference memory safety bugs as the String
each &str
points into is freed at the end of each iteration (e.g. all the &str
s in vect1
on the return vect1
line would be pointing to garbage).
To fix this, you need to cut the memory dependency: currently the &str
s are not in control of their own memory, and thus are dependent on the "parent" String
s being placed correctly. Instead, you could give the vector contents control of its own destiny (well, memory), by making them fully-fledged String
s, e.g. vect1.push(c1.to_string())
. This will make vect1
a Vec<String>
, and then there is no longer a connection between those values and the a_line
value inside the loop. That variable can then be freed/mangled/munged as much as it likes without affecting the contents of vect1
.