为什么编译器会拒绝此代码:
struct S<'a> {
i: i32,
r: &'a i32,
}
fn main() {
let mut s = S{i: 0, r: &0};
{
let m1 = &mut s;
m1.r = &m1.i;
}
let m2 = &mut s;
}
错误是:&#34;不能一次多次借用s
可变的&#34; (首先借用:m1
,第二次借用:m2
)。
为什么在s
超出范围后,m1
的第一次借用仍然存在?
我读到了超出原借款人范围的借款范围扩展。然而,这似乎总是涉及另一个借款人超出原借款人的范围,并且接管了#34;原始借款,例如这段代码失败并出现完全相同的错误,这对我来说很清楚:
fn main() {
let mut s = 0;
let r: &mut i32;
{
let m1 = &mut s;
r = m1;
}
let m2 = &mut s;
}
在第一个示例中,如果我将m1.r = &m1.i;
替换为m1.r = &dummy;
(虚拟定义为某些&amp; i32)或let dummy = &m1.i;
,则代码将进行编译。仅当我将引用存储在借用结构的另一个字段中时才会发生错误。我不明白为什么这会将借款扩展到其范围之外。
我最好猜测代码有什么问题:
s.r
原始生命周期是整个main
,
当我为m1.r
分配引用时,它必须是原始生命周期,但&m1.i
仅在m1
有效期内有效。
但我可能错了(错误信息会误导)。
答案 0 :(得分:6)
首先请注意
let mut s = S{i: 0, r: &0};
{
s.r = &s.i;
}
let m2 = &mut s;
给出
cannot borrow `s` as mutable because `s.i` is also borrowed as immutable
希望这应该是明确的 - 如果一个结构自我借用那么它就是借来的。这指出了为什么任何自借结构基本上没用 - 它不能移动(使自己的指针无效)也不能和可变引用一起使用。
接下来需要了解来自可变引用的不可变引用计入借入可变引用,因此扩展它。例如
let mut v = ();
let r1 = &(&mut v);
let r2 = &v;
给出
cannot borrow `v` as immutable because it is also borrowed as mutable
目前尚不清楚这是否能够合法地成为原始结构的新借款,但它仍然没有这样做。