为什么编译器会拒绝这段代码:
为什么在 `m1` 超出作用域之后, `s` 的第一个借用仍然存在?
我了解到有借用范围延伸的情况,但这通常涉及到原始借用者范围之外的另一个借用者“接管”了原始借用对象。例如,下面的代码会产生完全相同的错误,这对我来说非常明显:
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;
}
错误信息是:"不能同时将` s `借为可变引用超过一次"(第一次借用: `m1`,第二次借用: `m2`)。为什么在 `m1` 超出作用域之后, `s` 的第一个借用仍然存在?
我了解到有借用范围延伸的情况,但这通常涉及到原始借用者范围之外的另一个借用者“接管”了原始借用对象。例如,下面的代码会产生完全相同的错误,这对我来说非常明显:
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;
(其中dummy定义为某个&i32)或者let dummy = &m1.i;
,代码就可以编译。只有当我将借用结构体的另一个字段中的引用存储到另一个字段中时,才会出现错误。我不明白为什么这会延长borrow的范围。
我对代码存在问题的最佳猜测是:
s.r
的原始生命周期是整个main
函数,当我将引用分配给
m1.r
时,它必须是原始生命周期,但是&m1.i
只在m1
存活期内有效。
但我可能是错的(错误消息可能会误导人)。
&mut &mut T
)都受到它的限制。它所持有的借用的生命周期是无限的-考虑let x: &'static str = "foo"
。 - Veedracm1
是在m2
之前唯一的借用者。”→ 不,m1.r =&m1.i;
导致s
从m1
的借用中借用,因此s
从s
可变地借用。这显然将持续s
的生命周期。 - Veedracm1.r = &m1.i;
不会强制增加m1
的借用生命周期。显然它必须这样做。 - Veedracm1.r
从m1.i
中借用,没有从s
中进一步借用。我原本以为 Rust 编译器不会进行代码分析,因此无法“看到”m1.i
实际上是s.i
(就像你所说的是s
的借用)。 - dacker