我是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上不起作用?我已经阅读了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。请注意,这仅适用于引用,不适用于警戒或涉及生命周期的更复杂的类型(特别是不能调用drop
代码的任何事物)。