I have the following code, where I'm trying to return the struct Foo
with a set of default values for the field values
. These values may be changed later. But the compiler complains:
error: `initial` does not live long enough
How this could be achieved? Any alternatives?
struct Foo <'a> {
values: &'a mut Vec<i32>,
}
impl <'a> Foo <'a> {
fn new() -> Foo <'a> {
let initial = vec![1, 2];
Foo { values: &mut initial }
}
}
let my_foo = Foo::new();
my_foo.values.push(3);
There are two problems here.
The first is that you don't need to use
&mut
to make a structure field mutable. Mutability is inherited in Rust. That is, if you have aFoo
stored in a mutable variable (let mut f: Foo
), its fields are mutable; if it's in an immutable variable (let f: Foo
), its fields are immutable. The solution is to just use:and return a
Foo
by value.The second problem (and the source of the actual compilation error) is that you're trying to return a borrow to something you created in the function. This is impossible. No, there is no way around it; you can't somehow extend the lifetime of
initial
, returninginitial
as well as the borrow won't work. Really. This is one of the things Rust was specifically designed to absolutely forbid.If you want to transfer something out of a function, one of two things must be true:
It is being stored somewhere outside the function that will outlive the current call (as in, you were given a borrow as an argument; returning doesn't count), or
You are returning ownership, not just a borrowed reference.
The corrected
Foo
works because it owns theVec<i32>
.