环境:rustc 1.82.0(f6e511eec 2024-10-15)
问题:Rust 中的解引用与直接借用
*&T
我对借用中的和之间的区别感到困惑T
。以下代码使用编译let b = &mut *a
,但使用编译失败let b = &mut x
。为什么在这种情况下*a
的行为与不同x
?
此外,取消注释最后一行(*b = ...
)会导致错误:
无法分配给,
*a
因为它是借用的
fn annoying_borrow() {
let mut x = Box::new(1);
let a = &mut x;
let b = &mut *a;
// let b = &mut x; // error: cannot borrow `x` as mutable more than once at a time
*a = Box::new(2);
// *b = Box::new(3); // error: `*a` is assigned to here but it was already borrowed
}
这里用*a
代替是否进一步暗示了它们之间的细微差别?Emmm,我真正想探究的不是和x
之间的区别,而是 Rust 类型系统(编译器)中的借用规则。*a
x
背景:
我参考了《Programming Rust》第 2 版(第 5 章),但我无法完全理解这些知识:
共享访问是只读访问。
共享引用借用的值是只读的。在共享引用的整个生命周期中,无论是其引用对象还是从该引用对象可访问的任何对象,都不能被任何对象更改。该结构中不存在任何活动的可变引用,其所有者保持为只读状态,等等。它确实处于冻结状态。
可变访问是独占访问。
可变引用借用的值只能通过该引用访问。在可变引用的整个生命周期中,没有其他可用的路径可以到达其引用对象或任何可从那里访问的值。唯一可能与可变引用生命周期重叠的引用是从可变引用本身借用的引用。
不知道 Rust 中对借用有没有统一详细的解释,也许 Rust 中曾经有一套明确的借用规则,但是随着编译器不断放宽语法限制(为了方便某些场景的编码?),现在的规则就比较混乱了?
可变引用可以处于“非活动”状态。只有一个可变引用可以主动持有独占可变访问权限,但仅仅因为引用存在,并不意味着它拥有访问权限。当您通过可变引用借用时,该访问权限将转移到借用引用。
这意味着您可以通过具有访问权限的可变引用 a 创建可变引用 b,将访问权限从 a 转移到 b,直到 b 被删除并恢复为 a。当 b 存在时,您不能直接使用 a,因为它没有访问权限,就像 x 在 a 存在时没有访问权限一样。
此外,您可以从可变引用创建共享引用,在这种情况下,可变引用访问将降级为共享,直到从它借用的最后一个引用被删除。