如何在这里借用自我的多个部分?自我在这里不是一成不变地借来的吗? [英] How can multiple parts of self be borrowed here? Isn't self borrowed mutably as well as immutably here?

查看:46
本文介绍了如何在这里借用自我的多个部分?自我在这里不是一成不变地借来的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个结构:

struct PhysicsState {
    nodes: Vec<Node>,
    edges: Vec<Edge>,
}

并且我试图理解为什么此代码会编译:

and I'm trying to understand why this code compiles:

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 显然首先被借为不可变,然后是可变的,正如预期的那样失败了.

I originally used the first version and later changed it to the second, only to see it fail. And it makes sense to me that it fails. self is clearly borrowed as immutable first and then as mutable, which fails, as expected.

我不明白的是:第一个版本如何工作?

What I don't understand is: How does the first version work?

很显然,第一次借用(获取& Edge )必须在整个for循环中保持有效,因为它是在此循环中使用的.但是,如何从 self 那里获取对 Node 的附加可变引用呢?

Clearly the first borrow (getting the &Edge) has to stay alive throughout the for loop, since it is used there. But how does it manage to get an additional mutable reference to a Node from self then?

第二个版本的编译器返回的错误是: error [E0502]:无法借用* self为可变变量,因为它也借来为不可变

The error returned by the compiler for the second version is: error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable

为什么使用第一个版本时不会出现此错误?

Why don't I get this error when using the first version?

以防万一:

  • Node和Edge是简单的结构,没有实现Copy,所以这不是这里发生的事情
  • 之所以要切换到第二个版本,是因为那里的两个附加函数实际上包含要使用的类型强制转换,出于可读性的考虑,我在此处删除了这些类型转换,但是我必须在代码中的所有位置重复此操作没有这些功能.

也许我可以改用宏来达到相同的效果,但是总的来说,我只是想知道借用在这里是如何工作的,因为在我看来,我对此有某种误解.

Perhaps I could instead use a macro to achieve the same effect, but over all I just wanna know how the borrowing works here, because it seems to me that I have some kind of misunderstanding about it.

谢谢!

推荐答案

在第一个版本中,您可以借用 self.edges 并随后借用 self.nodes 的原因是因为编译器理解 self.edges self.nodes 分别是被借用的东西.这也称为"拆分借贷".与结构相关.

The reason you can borrow self.edges and subsequently self.nodes in your first version, is because the compiler understands that self.edges and self.nodes are individually what's being borrowed. This is also what's called "Splitting Borrows" in relation to structs.

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

However, if you opaquely look at the method signature:

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

然后,通过查看,您知道所借的是什么吗?并不真地.您所看到的就是它返回& Edge ,并且正在借用& self .因此,整个 self 是要借用的,这不允许您随后对 self.nodes 进行可变借用,因为 self 已经被不可更改地借用了

Then by looking at that, do you know what's being borrowed? Not really. All you can see is that it returns &Edge and &self is being borrowed. Thereby self as a whole is what's being borrowed, which disallows you doing the subsequent mutable borrow of self.nodes, because self is already immutably borrowed.

您本质上希望发生的事情是调用方法允许部分借用& self .Rust不支持此功能.但是,有一个可追溯至2015年的RFC要求此功能.RFC的标题为"部分借贷(#1215)",讨论潜在的语法和语义.

What you essentially desire occurring, is that calling methods allow &self to be partially borrowed. This is not supported in Rust. However, there is an RFC dating back to 2015 requesting this feature. The RFC is titled "Partial Borrowing (#1215)", which discusses potential syntax and semantics.

这篇关于如何在这里借用自我的多个部分?自我在这里不是一成不变地借来的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆