如果否则赋值 "move out of borrowed content"

If else assignment "move out of borrowed content"

这是一段 Rust 代码,用于在常见的二叉搜索树上执行插入操作。我想要对我将执行插入的分支的引用。

struct Node {
    value: i32,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl Node {
    fn insert(&mut self, elem: i32) {
        let ref mut a = if elem < self.value {
            self.left
        } else {
            self.right
        };

        // ...
    }
}

此代码无效。调整之后,我开始理解当我执行 if/else 语句时,Rust 在分配之前移动了内容。这个解决方案有效,但它真的很难看...

let a = if elem < self.value {
    let ref mut b = self.left;
    b
} else {
    let ref mut b = self.right;
    b
};

有没有办法在不重复使用 Box 的情况下处理这件事?我可以使用一个指针,但它看起来真的有点过分了。

注释后,这就是全部代码

fn insert(&mut self, elem: i32) {
    let target = if elem < self.value {
        &mut self.left
    } else {
        &mut self.right
    };

    match target.as_mut() {
        None => {}
        Some(ref mut node) => {
            node.insert(elem);
            return;
        }
    }

    mem::replace(&mut *target, Some(Box::new(Node::new(elem))));
}

正如您所观察到的,在您最初的尝试中,"then" 和 "else" 分支都试图 左侧或右侧框移出 &mut self 借用内容,不允许这样。

let ref mut a = if elem < self.value {
    self.left
} else {
    self.right
};

如您所说,您的第二次尝试编译成功但很丑陋。此代码通过ref mut 可变引用引用左右框来避免移出借用的内容。

let a = if elem < self.value {
    let ref mut b = self.left;
    b
} else {
    let ref mut b = self.right;
    b
};

通过可变引用来引用某物的更简洁的方法是使用 &mut 运算符。 if-statement 应该是:

let a = if elem < self.value {
    &mut self.left
} else {
    &mut self.right
};