这里怎么能借用自我的多个部分呢?这里的自借不是可变的和不变的吗?

2024-01-12

我有这个结构:

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!


您可以借钱的原因self.edges随后self.nodes在你的第一个版本中,是因为编译器理解self.edges and self.nodes分别是所借的内容。这也是所谓的“分割借款 https://doc.rust-lang.org/nomicon/borrow-splitting.html“ 与结构有关。

但是,如果您不透明地查看方法签名:

fn edge_at(&self, edge_index: usize) -> &Edge

那你看一看,知道借的是什么吗?并不真地。你所看到的只是它返回了&Edge and &self正在借用。从而self作为一个整体是被借用的,这不允许您进行后续的可变借用self.nodes, 因为self已经是一成不变的借用了。


您本质上希望发生的是调用方法允许&self部分借用。 Rust 不支持这一点。然而,有一个可追溯到 2015 年的 RFC 请求此功能。 RFC 的标题是“部分借用 (#1215) https://github.com/rust-lang/rfcs/issues/1215”,其中讨论了潜在的语法和语义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这里怎么能借用自我的多个部分呢?这里的自借不是可变的和不变的吗? 的相关文章

随机推荐