我希望这段代码能够正常工作,因为所有绑定都在同一范围内:
fn main() {
let mut foobar = vec!["foo"];
let bar = "bar".to_string();
foobar.push(&bar);
}
但是我收到了这个错误:
error: `bar` does not live long enough
--> baz.rs:4:18
|>
4 |> foobar.push(&bar);
|> ^^^
note: reference must be valid for the block suffix following statement 0 at 2:33...
--> baz.rs:2:34
|>
2 |> let mut foobar = vec!["foo"];
|> ^
note: ...but borrowed value is only valid for the block suffix following statement 1 at 3:32
--> baz.rs:3:33
|>
3 |> let bar = "bar".to_string();
|> ^
error: aborting due to previous error
答案 0 :(得分:10)
在同一个块中声明的变量将按与声明它们相反的顺序删除。在您的代码中,bar
之前会删除foobar
:
fn main() {
let mut foobar = vec!["foo"]; // <---------| 0
let bar = "bar".to_string(); // <--| 1 |
foobar.push(&bar); // | bar | foobar
// <--| |
// <---------|
// In the error message
// 0 is called "block suffix following statement 0", and
// 1 is called "block suffix following statement 1"
}
您正在bar
中将引用推送到foobar
,因此您必须确保bar
的生命至少与foobar
一样长。但由于bar
是在foobar
之后宣布的,因此bar
的生命周期实际上比foobar
更短,这意味着foobar
包含一个短暂的悬挂参考。
要编译代码,请在bar
之前声明foobar
:
fn main() {
let bar = "bar".to_string();
let mut foobar = vec!["foo"];
foobar.push(&bar);
}
或选择加入non-lexical lifetimes:
#![feature(nll)]
fn main() {
let mut foobar = vec!["foo"];
let bar = "bar".to_string();
foobar.push(&bar);
}
虽然这仍然有一个悬空参考,但这并不重要,因为删除引用什么都不做; Vec
在删除时不需要使用其中包含的引用值。