【问题标题】:Rust: "cannot move out of `self` because it is borrowed" errorRust:“无法移出‘self’,因为它是借来的”错误
【发布时间】:2014-04-27 20:38:40
【问题描述】:

我正在尝试编写一个递归方法,将一个项目添加到树中并返回与该项目对应的树节点。

enum BstNode {
    Node(int, ~BstNode, ~BstNode),
    Leaf
}

impl BstNode {
    fn insert<'a>(&'a mut self, item: int) -> &'a mut BstNode {
        match *self {
            Leaf => {
                *self = Node(item, ~Leaf, ~Leaf);
                self
            },
            Node(ref node_item, ref mut left, ref mut right) =>
                match item.cmp(node_item) {
                    Less => left.insert(item),
                    Equal => self,
                    Greater => right.insert(item)
                }
        }
    }
}

我被以下错误所困扰:

bst.rs:19:30: 19:34 error: cannot move out of `self` because it is borrowed
bst.rs:19                     Equal => self,
                                       ^~~~
bst.rs:16:18: 16:31 note: borrow of `self#0` occurs here
bst.rs:16             Node(ref node_item, ref mut left, ref mut right) =>
                           ^~~~~~~~~~~~~

“搬出something”是什么意思?如何解决此错误?

我正在使用 Rust 0.10。

【问题讨论】:

    标签: pattern-matching rust lifetime


    【解决方案1】:

    在您的示例中,node_itemleftrightself 变量所有。借用检查器不知道在

    的 Equal 分支中
    match item.cmp(node_item) {
        Less => left.insert(item),
        Equal => self,
        Greater => right.insert(item)
    }
    

    既没有使用node_itemleft 也没有使用right,但它看到self 正在移动(您正在返回它)而这三个变量仍然被借用(您仍然在匹配,它们被借用的地方)。我认为这是一个已知的错误,即这种行为过于严格,请参阅issue #6993

    至于修复代码的最佳方法,老实说我不确定。我会使用完全不同的结构(至少在修复之前的错误之前):

    pub struct BstNode {
      item: int,
      left: Option<~BstNode>,
      right: Option<~BstNode>
    }
    
    impl BstNode {
        pub fn insert<'a>(&'a mut self, item: int) -> &'a mut BstNode {
            match item.cmp(&self.item) {
                Less => match self.left {
                  Some(ref mut lnode) => lnode.insert(item),
                  None => {
                    self.left = Some(~BstNode {item: item, left: None, right: None});
                    &mut **self.left.as_mut().unwrap()
                  }
                },
                Equal => self,
                Greater => match self.right {
                  Some(ref mut rnode) => rnode.insert(item),
                  None => {
                    self.right = Some(~BstNode {item: item, left: None, right: None});
                    &mut **self.right.as_mut().unwrap()
                  }
                }
            }
        }
    }
    

    这样,当您归还节点时,您永远不会有任何成员被借用。

    【讨论】:

    • 谢谢!在保留数据结构的同时修复我的代码的方法结果是匹配Node(node_item, _, _)(注意缺少ref)并通过Less/Greater分支中的另一个模式匹配提取左/右。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    相关资源
    最近更新 更多