Reputation: 1593
Why can I run the following statement without issues?
println!("{:?}", (vec!["1".to_string(), "1".to_string(), "1".to_string()]).iter().collect::<Vec<&String>>());
If I understood it correctly, it creates an array of owned Strings, get's an iterator of String references and then collects an array of String references. But these references refer to an array that ceased existing in the beginning of that statement. Why does it work?
Upvotes: 2
Views: 59
Reputation: 16925
The lifetime is extended till the end of the statement (i.e. the semicolon), not at the end of .iter()
.
The compiler explains this when you split this code into two statements.
In the Rust Reference we find this:
Apart from lifetime extension, the temporary scope of an expression is the smallest scope that contains the expression and is one of the following:
- The entire function body.
- A statement.
- The body of an if, while or loop expression.
- The else block of an if expression.
- The condition expression of an if or while expression, or a match guard.
- The expression for a match arm.
- The second operand of a lazy boolean expression.
In this case, the smallest scope is the statement.
fn main() {
let v = (vec!["1".to_string(), "1".to_string(), "1".to_string()])
.iter()
.collect::<Vec<&String>>(); // !!! ERROR
println!("{:?}", v);
}
...
4 | .collect::<Vec<&String>>();
| - temporary value is freed at the end of this statement
...
Upvotes: 7