rust 返回对块中创建的变量的引用

svujldwt  于 2023-01-05  发布在  其他
关注(0)|答案(1)|浏览(133)

此代码无法编译:

let y = {
    let x = "foo".to_owned();
    &x
};
dbg!(y);

但这段代码可以:

let y = {
    let x = "foo".to_owned();
    &x.clone()
};
dbg!(y);

我以为我们不能返回对局部变量的引用,但在这个例子中我们可以。x.clone()是在块内部创建的,但我们可以在块外部获得对它的引用。然而我们不能在x上做同样的事情。这里发生了什么?

ffx8fchx

ffx8fchx1#

临时生存期延长的规则有点复杂,但是这个问题中的两个代码片段的区别可以归结为:

只有在块的最终表达式中创建的值才会应用生存期扩展。

  • 在第二个块(编译)的情况下,clone()的返回值的生存期延长了,因为它是在块的最终表达式中创建的。
  • 另一方面,在第一个代码块(编译失败)中,初始化器代码块的最终表达式是对前一条语句中创建的变量的引用,这意味着 temporary lifetime extension 没有被应用,实际上,当你这样看时,它是有意义的,因为x不是一个 temporary,而是一个实际的命名变量。

在Rust参考文献中是这样解释的:
对于带有初始化式的let语句,扩展表达式是......任何扩展块表达式的最终表达式。
...
任何扩展借位表达式的操作数都扩展了其临时作用域。
-- rust eclipse 参考第10.8节,临时寿命延长
另见:
Code in Rust Playground

相关问题