繁体   English   中英

为什么编译器错误抱怨多个可变引用而不是悬挂引用?

[英]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_funaa重新借用为&*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_funaa重新借用为&*aa ,其 scope 将是my_fun

不完全是这样。

让我们回顾一下:为什么要重新借用?

&T&mut T之间存在根本区别: &TCopy ,而&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_funaa重新借用为&*aa ,其 scope 将是my_fun

生命周期通常更像是一个范围而不是一个,这里也是如此。

在我上面的示例中, tmp的生命周期受到两种方式的限制:

  • 它不能大于x的值。
  • 它不能小于func的值。

这是另一种说法,它可以是这些界限之间的任何东西

我相信你在这里过度思考“重新借用”。

您应用的生命周期要求表示返回值引用的事物至少具有参数引用的事物的生命周期。 这是真的(如果不能证明是真的,这将无法编译)。 所以不可能有悬空引用。

没有单独的“重新借用”参考。 借用是编译器内部的簿记,以跟踪生命周期。 没有实际发生或什至特别暗示的let x = &*aa步骤。 这不像引用计数,其中 memory 实际上在运行时发生变化。

my_fun内部, y是一个范围为 function 的引用。但返回值的范围为调用者。 (如果这不是真的,函数将无法使用,与&mut无关。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM