![](/img/trans.png)
[英]Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?
[英]Why does the compiler error complain about multiple mutable references not dangling reference?
我试图了解当函数重新借用可变引用时到底发生了什么。
fn main() {
let mut a = String::new();
let mut b = String::new();
let aa = &mut a;
let c = my_fun(aa, &mut b);
let d = &mut a;
println!("{}", c);
}
fn my_fun<'b>(x: &'b mut String, y: &'b mut String) -> &'b mut String { y }
根据我的理解, my_fun
将aa
重新借用为&*aa
,其 scope 将是my_fun
。 但是由于我在 function 签名中创建的生命周期限制,reborrow 应该至少在&mut b
存在时存在。 所以println
强制重新借用直到它。
这不应该在 free 之后引发使用错误,因为匿名重新借用在 my_fun 中只有my_fun
吗? 在这个 function 之外,这个引用应该是无效的。
但我得到的错误是:
error[E0499]: cannot borrow `a` as mutable more than once at a time
--> src/main.rs:7:13
|
5 | let aa= &mut a;
| ------ first mutable borrow occurs here
6 | let c = my_fun(aa, &mut b);
7 | let d = &mut a;
| ^^^^^^ second mutable borrow occurs here
8 | println!("{}", c);
| - first borrow later used
如果可变引用只是被复制而不是在 function 中重新借用,这将是有意义的。
根据我的理解,
my_fun
将aa
重新借用为&*aa
,其 scope 将是my_fun
。
不完全是这样。
让我们回顾一下:为什么要重新借用?
&T
和&mut T
之间存在根本区别: &T
是Copy
,而&mut T
甚至不是Clone
。 结果是&mut T
只能移动,因此调用如下:
let x: &mut T = /*...*/;
func(x);
会导致x
在调用后无法使用。 解决方法是引入一个临时的:
let x: &mut T = /*...*/;
let tmp = &mut *x;
func(tmp);
这个临时对象将重新借用x
的指针对象,并由func
消耗。
还有……那是再借! 编译器内置了这种“临时”创建,纯粹是为了符合人体工程学!
考虑到这一点,让我们 go 回到:
根据我的理解,
my_fun
将aa
重新借用为&*aa
,其 scope 将是my_fun
。
生命周期通常更像是一个范围而不是一个点,这里也是如此。
在我上面的示例中, tmp
的生命周期受到两种方式的限制:
x
的值。func
的值。这是另一种说法,它可以是这些界限之间的任何东西。
我相信你在这里过度思考“重新借用”。
您应用的生命周期要求表示返回值引用的事物至少具有参数引用的事物的生命周期。 这是真的(如果不能证明是真的,这将无法编译)。 所以不可能有悬空引用。
没有单独的“重新借用”参考。 借用是编译器内部的簿记,以跟踪生命周期。 没有实际发生或什至特别暗示的let x = &*aa
步骤。 这不像引用计数,其中 memory 实际上在运行时发生变化。
在my_fun
内部, y
是一个范围为 function 的引用。但返回值的范围为调用者。 (如果这不是真的,函数将无法使用,与&mut
无关。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.