In Rust, we can delay the initialization of variables like this:
let v;
// some other statements
v = &0;
However, when using the references of return values for the delay initialization of variables like this:
let v;
v = &String::from("hello");
The compiler reported an error. So did I violate some principles of the delay initialization of variables? Here is the error information.
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:10:10
|
10 | v = &String::from("hello");
| ^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
11 | println!("{}", v);
| - borrow later used here
|
help: consider using a `let` binding to create a longer lived value
|
10 ~ let binding = String::from("hello");
11 ~ v = &binding;
|
For more information about this error, try `rustc --explain E0716`.
The error is exactly what the compiler says. A temporary is just that – a temporary, ie., it goes out of scope immediately (the precise rules are more complicated, but this is all what matters here). Thus, returning a reference to it would create a dangling reference.
Your example with the literal &0 shouldn't work, either, but it still does due to certain constant expressions undergoing so-called "static promotion" (google it).
BTW, when you need values, use values. Don't try to "return by reference". You are probably misunderstanding what references are for — you can't use them for keeping values alive.
Thanks for your answer, I know this code snippet may not follow the design of Rust.
However, if I change this snippet into this:
let v = &String::from("hello");
It works well. So I guess this question may be related to the delay initialization, for I expect the reference is bound to the variable when executing v = &String::from("hello") and the variable will hold the temporary value. But actually, there is no binding and the value is dropped.
With let var = &expr, the temporaries in expr have their lifetime extended to match that of var. For var = &expr, this temporary lifetime extension does not happen. This has nothing to do with delayed intialization of variables. The following has the exact same issue:
let mut v = &String::from("hello");
v = &String::from("world");
println!("{v}");
And here too only the v = ... is reported as error. The let mut v = ... is accepted.
According to your words, there should be some difference between normal initialization and delayed initialization? Since in this situation, delayed initialization works like just normal assignment.