当前位置:  开发笔记 > 后端 > 正文

在函数参数中解构包含借位的结构

如何解决《在函数参数中解构包含借位的结构》经验,为你挑选了0个好方法。

我正在尝试实现一个使用借用检查/生命周期的系统,以便为集合提供安全的自定义索引.请考虑以下代码:

struct Graph(i32);

struct Edge<'a>(&'a Graph, i32);

impl Graph {
    pub fn get_edge(&self) -> Edge {
        Edge(&self, 0)
    }

    pub fn split(&mut self, Edge(_, edge_id): Edge) {
        self.0 = self.0 + edge_id;
    }

    pub fn join(&mut self, Edge(_, edge0_id): Edge, Edge(_, edge1_id): Edge) {
        self.0 = self.0 + edge0_id + edge1_id;
    }
}


fn main() {
    let mut graph = Graph(0);
    let edge = graph.get_edge();
    graph.split(edge)
}

Edge当调用诸如splitjoin调用方法时,应删除对结构借用的图形的引用.这将满足API不变量,即在图形变异时必须销毁所有边缘索引.但是,编译器没有得到它.它失败的消息就像

error[E0502]: cannot borrow `graph` as mutable because it is also borrowed as immutable
  --> src/main.rs:23:5
   |
22 |     let edge = graph.get_edge();
   |                ----- immutable borrow occurs here
23 |     graph.split(edge)
   |     ^^^^^ mutable borrow occurs here
24 | }
   | - immutable borrow ends here

如果我理解正确,编译器就无法意识到在调用函数时实际上正在释放边缘结构中发生的图形的借用.有没有办法教我编译器在这里尝试做什么?

奖金问题:有没有办法完全相同但没有实际借用Edge结构中的图形?边缘结构仅用作遍历的临时目的,并且永远不会成为外部对象状态的一部分(我的边缘有'弱'版本).

附录:经过一番挖掘,似乎真的很琐碎.首先,Edge(_, edge_id)实际上并没有对结构进行解构Edge,因为_根本没有绑定(是的,i32复制使事情变得更加复杂,但这很容易通过将其包装到非复制结构中来解决).其次,即使我完全解构Edge(即通过在单独的范围内进行),对图形的引用仍然存在,即使它应该被移动(这必定是一个bug).它只有在我在单独的函数中执行解构时才有效.现在,我知道如何绕过它(通过一个单独的对象描述状态变化并在提供索引时对其进行解构),但这很快变得非常尴尬.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有