为什么允许这样做:
fn main() {
let mut w = MyStruct;
w.fun1();
}
struct MyStruct;
impl MyStruct {
fn fun1(&mut self) {
self.fun2();
}
fn fun2(&mut self) {
println!("Hello world 2");
}
}
在上面的代码中,fun1()
得到mut MyStruct
并用fun2()
调用mut MyStruct
。它是在一个范围内双重可变引用吗?
这是允许的,因为借用检查器可以得出结论,在执行过程中仅访问了一个可变引用。当fun2
运行时,fun1
中没有其他语句正在执行。当fun1
中的下一条语句(如果有)开始执行时,fun2
已经删除了其可变引用。
在链接的另一个问题中:
fn main() {
let mut x1 = String::from("hello");
let r1 = &mut x1;
let r2 = &mut x1;
r1.insert(0, 'w');
}
我们可以说从未使用过r2
,但借阅检查器决定不应使用它。考虑这个例子:
fn main() {
let mut x1 = String::from("hello");
let r1 = &mut x1;
r1.insert(0, 'w');
let r2 = &mut x1;
r2.insert(0, 'x');
}
这将编译并正确运行。我想借用检查器假定生存期r1
在创建r2
之前结束。如果这是有道理的,那么调用使self
突变的方法就不会感到惊讶。
((我不知道为什么第一段代码无法编译,但是我很高兴锈团队做到了。r2
仍然不应该在那里。)