我有这个结构:
struct PhysicsState {
nodes: Vec<Node>,
edges: Vec<Edge>,
}
我试图理解为什么这段代码可以编译:
impl PhysicsState {
fn remove_edge(&mut self, edge_index: usize) {
let edge = &self.edges[edge_index]; // first borrow here
// update the edge-index collection of the nodes connected by this edge
for i in 0..2 {
let node_index = edge.node_indices[i];
self.nodes[node_index].remove_edge(edge_index); // second (mutable) borrow here ?
}
}
}
虽然这失败了:
impl PhysicsState {
pub fn edge_at(&self, edge_index: usize) -> &Edge {
&self.edges[edge_index]
}
pub fn node_at_mut(&mut self, node_index: usize) -> &mut Node {
&mut self.nodes[node_index]
}
fn remove_edge(&mut self, edge_index: usize) {
let edge = self.edge_at(edge_index); // first (immutable) borrow here
for i in 0..2 {
let node_index = edge.node_indices[i];
self.node_at_mut(node_index).remove_edge(edge_index); // second (mutable) borrow here -> ERROR
}
}
}
}
我本来用的是第一个版本,后来改成了第二个,结果失败了。
它的失败对我来说是有道理的。self
显然首先借用为不可变的,然后借用为可变的,这正如预期的那样失败了。
我不明白的是:第一个版本是如何工作的?
显然第一个借用(得到&Edge
) 必须在整个 for 循环中保持活动状态,因为它在那里被使用。但是它如何设法获得对 a 的额外可变引用Node
from self
then?
第二个版本的编译器返回的错误是:error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
为什么我在使用第一个版本时没有收到此错误?
如果您想知道:
- Node 和 Edge 是简单的结构,没有实现 Copy,所以这不是这里发生的情况
- 我想切换到第二个版本的原因是,那里的两个附加函数实际上包含要使用的类型转换,为了可读性,我在此处删除了它们,但是如果没有这些函数,我必须在代码中的所有位置重复它们。
也许我可以使用宏来达到相同的效果,但总的来说,我只是想知道这里的借用是如何工作的,因为在我看来,我对此有某种误解。
Thanks!