理解 Rust 中的引用生命周期

Understanding of reference life time in Rust

我是 Rust 的新用户,我正在阅读一本书 完整的 Rust 编程参考指南。书中有一个例子:

fn main() {
    let mut a = String::from("testing");
    let a_ref = &mut a;
    a_ref.push('!');

    println!("{}", a);
}

书上说代码会产生错误。

但是,在我的本地计算机上,我可以 运行 它没有任何问题。这是因为我使用的是较新的 Rust 编译器 [rustc 1.41.0-nightly (412f43ac5 2019-11-24)] 而代码不适用于旧版本吗?我已经阅读了 Rust 官方书籍的一些章节。据我了解,引用 a_ref 的生命周期在其最后一次使用时结束,即 a_ref.push('!');。在那之后 a_ref 消失了, a 应该可以毫无问题地使用。我的理解正确吗?

最有可能发生的情况是,您正在阅读的书在教授生命周期,而忽略了非词汇生命周期。这是有道理的;词法生命周期是最容易理解的。

运行 以下将恢复到非词汇生命周期出现之前:

rustup default 1.30

这会将 rustc 恢复到 1.31 之前的版本,根据 this 文档,这是 nll 的最低版本。

运行 这会导致与所示完全相同的错误:

> cargo run
   Compiling forum_examples v0.1.0 (C:\Users\user\Desktop\forum_examples)
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
 --> src\main.rs:6:20
  |
3 |     let a_ref = &mut a;
  |                      - mutable borrow occurs here
...
6 |     println!("{}", a);
  |                    ^ immutable borrow occurs here
7 | }
  | - mutable borrow ends here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: Could not compile `forum_examples`.

To learn more, run the command again with --verbose.

您可以选择使用此版本的编译器(或 2015 版的 1.35 版)来严格按照本书的要求进行操作,或者您可以使用此经验法则来确定为什么它没有根据本书进行编译但对今天的编译器有影响:如果编译器发现不再需要引用,它将删除引用。在您的示例中,编译器发现之后不再需要 a_ref ,因此它会在之后插入一个隐式删除。请注意,这仅适用于引用,不适用于守卫或涉及生命周期的更复杂类型(尤其是任何可以调用 drop 代码的类型)。