"活得不够长"同一功能中的错误

时间:2016-06-24 23:05:59

标签: rust

我希望这段代码能够正常工作,因为所有绑定都在同一范围内:

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

1 个答案:

答案 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在删除时不需要使用其中包含的引用值。