Is it possible to push a pointer into a Vec in the following manner?
fn foo(v: &mut Vec<&T>) -> Result<(), io::Error> {
let e = try!(some_io_that_may_return_a_T());
v.push(&e);
Ok(())
}
The borrow checker is telling me that e does not live long enough which I think I understand. That would be a borrow which would be dead after foo is done executing.
Is there a way to specify the lifetime so that the pointer to e survives?
The following works but it's copying e so that the vector takes ownership and I want to avoid the copy.
fn foo(v: &mut Vec<T>) -> Result<(), io::Error> {
let e = try!(some_io_that_may_return_a_T());
v.push(e);
Ok(())
}
Try to think about & as link to something which have to exists. Pointers aren't real objects as it sometimes happens with C/C++. If you have & you also have an object somewhere. Boxing above is good solution.
Sometimes I'm thinking that wasn't good idea to use & as borrowing operator, anybody confused it, but my fingers have accustomed to type that symbol, and really it isn't a bad idea to use &.
I always considered the & operator in Rust as a super powered version of the same operator in C++. In Rust it has a superset of the C++ features in that it not only is the address-of operator but also defines a lifetime beyond a binding's local scope.
The primary reason explicit syntax for lifetimes is necessary is to make sure lifetime checking the body of one function doesn't depend on the body of any other functions. This is good for many reasons: it allows documenting the lifetime bounds of functions and types, it makes compiler error messages easier to understand, it allows functions containing unsafe code to enforce lifetimes for the inputs and outputs, and it makes it easier to write the compiler.
That's correct. But semantic has much difference. Look at this:
// Rust version
fn main() {
let first = 10;
let second = &first;
let third = first + second;
println!("{}", third);
}
// C version
int main() {
int first = 10;
int* second = &first;
int third = first + *second;
printf("%d", third);
}
With C case reference has produced a really another type, but with Rust you have the same type was borrowed. You can imagine that the reference lays deeper and can't be used safety as independent unit.
For your example above lifetimes can track the data have lost. Rust is still low-level language and you have to choose where to store the data: in stack or heap. In cases of changing owners data also can be copied, but you can use unsafe tools to change that.