< 返回版块

挺肥 发表于 2020-02-25 10:04

根据借用检查规则,以下代码会报错

let mut v = vec![1, 2, 3, 4, 5];

let third = &v[0]; 

v.push(6); // cannot borrow `v` as mutable because it is also borrowed as immutable

println!("third is {}", third);

但是为什么将最后一行去掉之后,代码就不会报错了呢?

let mut v = vec![1, 2, 3, 4, 5];

let third = &v[0];

v.push(6);

按我的理解就算没有使用变量 third 也违反了借用规则呀,求赐教

评论区

写评论
作者 挺肥 2020-02-28 09:53

懂了!谢谢各位

zydxhs 2020-02-25 20:28

Rust - None Lexical Lifetimes (NLL) 使用指南:https://zhuanlan.zhihu.com/p/32884290

对以下内容的回复:

zydxhs 2020-02-25 20:25

请先了解下 NLL(非词法作用域生命周期)。Rust 在引入 NLL 之前,是不能同时存在 共享引用 和 可变引用 的;在引入 NLL 之后,两者表面上可以同时存在,实际上不然,它是为了方便书写,减少手动书写 {} 代码块,两者不能交叉使用。

Krysme 2020-02-25 18:44

这样的设定是对的,因为野指针不去使用它,并不算有内存问题,这样的设定可以降低false positive

心情好又暖 2020-02-25 10:32

以下内容来自Rust 程序设计语言(第二版)

注意一个引用的作用域从声明的地方开始一直持续到最后一次使用为止。例如,因为最后一次使用不可变引用在声明可变引用之前,所以如下代码是可以编译的:

let mut s = String::from("hello");

let r1 = &s; // 没问题
let r2 = &s; // 没问题
println!("{} and {}", r1, r2);
// 此位置之后 r1 和 r2 不再使用

let r3 = &mut s; // 没问题
println!("{}", r3);

不可变引用 r1 和 r2 的作用域在 println! 最后一次使用之后结束,这也是创建可变引用 r3 的地方。它们的作用域没有重叠,所以代码是可以编译的。 尽管这些错误有时使人沮丧,但请牢记这是 Rust 编译器在提前指出一个潜在的 bug(在编译时而不是在运行时)并精准显示问题所在。这样你就不必去跟踪为何数据并不是你想象中的那样。

Rynco Maekawa 2020-02-25 10:28

third 的借用时间持续到你最后一次使用它。第二段代码中在 v.push(6) 之后没有再使用过 third,所以不会报错。详见 Rust 的 NLL 说明: https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/non-lexical-lifetimes.html

1 共 6 条评论, 1 页