Rust 从可变引用中重新借用共享引用

问题描述 投票:0回答:1

我是 Rust 新手,并试图理解为什么对已借用元素的数据结构的可变引用似乎可以在同一生命周期内再次使用来借用另一个元素。这是 O'Reilly 一本关于 Rust 的书中的一个例子,这让我有些困惑:

let mut v = (136, 139);
let m = &mut v;
let m0 = &mut m.0;   //ok: reborrowing mutable from mutable
*m0 = 137;
let r1 = &m.1;       //ok: reborrowing shared from mutable,
                     //and doesn't overlap with m0
v.1;                 //error: access through other paths still forbidden
println!("{}", r1);  //r1 gets used here

书中提到:

在可变引用的生命周期中,没有其他可用路径到达其所指对象或从那里可到达的任何值。生命周期可能与可变引用重叠的唯一引用是您从可变引用本身借用的引用。

然后,本书给出了一个图表(“所有权树”),显示了值树(在引用允许的情况下,子节点可以通过父节点引用,例如具有数据结构的元素,其中该元素是子节点和父节点(数据结构),具有可变引用,因为从它开始的引用路径必须是不可访问的,而其引用对象及其下面的引用路径只能通过它访问。同样,对于共享引用,给出了一个类似的树形图,显示了从它向上的路径上的所有引用,这些引用可以使用该路径引用它,因为必须是只读的,以及该引用和从它可到达的引用是只读的。

所以让我困惑的是上面的第五行(

let r1 = &m.1;

),以及为什么它可以。我相信我理解 
m
 只是借用了 
v
,这很好;但然后
m0
借用了
m.0
(或者这在技术上是来自
m
?),我认为根据上面的引用和树图解释意味着
m
不能再次在这里使用,直到
m0结束
 的生命周期,因为 
m
 指的是内存中的数据结构,位于“所有权树”中从 
m0
 向上的概念路径上。 (即,
m0
的值可以从
m
到达。)

总而言之,我认为在上面第3行借用了

m

之后,
m0
就不能再在这里使用了,但它却在上面第5行引用了
m.1
。我试图理解为什么这样可以。我感觉是因为上面那句话最后一句“谁的一生可能有重叠”,但还是感觉有些矛盾。在上面的评论中,它写着“并且不与
m0
重叠”,尽管
m
可以同时到达
m.0
m.1
,因此出现在“所有权树”中,所以我认为无法使用/不可访问(从而阻止在第 5 行通过它访问 
m.1
),同时对 
m.0
 的可变引用处于活动状态。

rust lifetime borrow-checker ownership mutable-reference
1个回答
0
投票
正如你自己所说的那样

生命周期可能与可变引用重叠的唯一引用是那些从可变引用本身借用的引用。

您正在借用可变引用,所以没关系。它没有在哪里说你被限制只能从中可变地借钱,而且你并不像你所证明的那样。

换句话说,您可以随心所欲地从可变引用中借用,它们甚至会强制共享引用。

因为

非词汇生命周期m0

不必超出
m
可重借的范围,即使它借用了与
r1
相同的片段,但它甚至不这样做,所以正如 PitaJ 指出的那样,编译器能够
分割借用

© www.soinside.com 2019 - 2024. All rights reserved.