我有这个结构体:
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循环中保持活动状态,因为它在其中被使用。但是,它又是如何设法从self
获得一个额外的可变引用到Node
的呢?
编译器返回第二个版本的错误信息是:error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
为什么我在使用第一个版本时没有遇到这个错误呢?
如果你想知道原因:
Node
和Edge
是简单的结构体,没有实现Copy,所以不是这里发生的事情- 我想切换到第二个版本的原因是,那里的两个额外函数实际上包含了类型转换为usize,我为了可读性将其删除了,但是如果没有这些函数,我就必须在我的代码中重复使用它们。
也许我可以使用宏来实现相同的效果,但总体来说,我只想知道这里的借用是如何工作的,因为对我来说,我对它有一些误解。
谢谢!