ошибка "не живет достаточно долго" в той же функции

Я ожидал, что этот код будет работать, потому что все привязки находятся в одной области:

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 ответов


переменные, объявленные в том же блоке, удаляются в обратном порядке. В коде 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"
}

вы толкаете ссылка to bar на foobar, так что вы должны убедиться, что bar жизнь, по крайней мере пока foobar. Но потому что bar объявлена после foobar, barсрок службы на самом деле короче, чем foobar's, что означает, что foobar содержит подвешенные на короткий момент.

, чтобы скомпилировать код, объявить bar до foobar:

fn main() {
    let bar = "bar".to_string();
    let mut foobar = vec!["foo"];
    foobar.push(&bar);
}

и зарегистрироваться в не-лексико жизни:

#![feature(nll)]

fn main() {
    let mut foobar = vec!["foo"];
    let bar = "bar".to_string();
    foobar.push(&bar);
}

хотя это все еще имеет висячую ссылку, это не имеет значения, потому что удаление ссылки ничего не делает;Vec не нужно использовать значение ссылок, которые он содержит, когда он отброшен.