为什么我可以调用 iter 并内联收集而不会出现生命周期问题?

Dan*_*ães 2 rust borrow-checker

为什么我可以毫无问题地运行以下语句?

println!("{:?}", (vec!["1".to_string(), "1".to_string(), "1".to_string()]).iter().collect::<Vec<&String>>());
Run Code Online (Sandbox Code Playgroud)

如果我理解正确的话,它会创建一个拥有的字符串数组,获取一个字符串引用的迭代器,然后收集一个字符串引用数组。但这些引用引用了一个在该语句开头就不存在的数组。为什么它有效?

pro*_*-fh 7

生命周期会延长到语句末尾(即分号),而不是 的末尾.iter()

当您将此代码拆分为两个语句时,编译器会对此进行解释。

Rust 参考文献中,我们发现了这一点:

除了生命周期扩展之外,表达式的临时作用域是包含该表达式的最小作用域,并且是以下之一:

  • 整个函数体。
  • 一份声明。
  • if、while 或循环表达式的主体。
  • if 表达式的 else 块。
  • if 或 while 表达式或匹配守卫的条件表达式。
  • 火柴臂的表达式。
  • 惰性布尔表达式的第二个操作数。

在这种情况下,最小的范围是语句。

fn main() {
    let v = (vec!["1".to_string(), "1".to_string(), "1".to_string()])
        .iter()
        .collect::<Vec<&String>>(); // !!! ERROR
    println!("{:?}", v);
}
Run Code Online (Sandbox Code Playgroud)
...
4 |         .collect::<Vec<&String>>();
  |                                   - temporary value is freed at the end of this statement
...
Run Code Online (Sandbox Code Playgroud)