From the Rust Reference:
Temporary lifetimes
When using a value expression in most place expression contexts, a temporary unnamed memory location is created initialized to that value and the expression evaluates to that location instead
This applies, because String::new()
is a value expression and being just below &mut
it is in a place expression context. Now the reference operator only has to pass through this temporary memory location, so it becomes the value of the whole right side (including the &mut
).
When a temporary value expression is being created that is assigned into a let declaration, however, the temporary is created with the lifetime of the enclosing block instead
Since it is assigned to the variable it gets a lifetime until the end of the enclosing block.
This also answers this question about the difference between
let a = &String::from("abcdefg"); // ok!
and
let a = String::from("abcdefg").as_str(); // compile error
In the second variant the temporary is passed into as_str()
, so its lifetime ends at the end of the statement.
&x
takes the address ofx
, and I believe that this is never valid for temporaries. I should probably have compared this to creating a reference to a temporary, which is indeed possible, and even expands the lifespan of the temporary, so overall the behaviour is actually quite similar to what Rust does. – Maynardstruct T { T* me() { return this; } };
will return you the address of the instance ofT
regardless of whether it's a temporary or not. Furthermore, C++ allows binding a const-reference or r-value reference to temporaries, and a reference it little more than a pointer in disguise. – Trifurcate&temp
just because the syntax looks similar. – Maynardint& v = 5; v+=1; std::cout << v;
Or even do such thing:auto& v = classname().field_name; std::cout << v;
– Dextroerror[E0716]
error E0716: temporary value dropped while borrowed (rust). It links back to this Question. – Carangid