Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Change the root node in a binary tree

I wrote a binary tree of i32. I want to change its root node to left node. But always failed. How to do it?

fn left(&mut self) -> Result<(), Error> {
        match self.root.as_mut() {
            Some(root) => match root.left {
                Some(left) => {
                    self.root = Some(left); // this line always failed
                    return Ok(());
                }
                None => {
                    return Err(Error::NotFound);
                }
            },
            None => {
                return Err(Error::EmptyTree);
            }
        }
    }

self.root = Some(left) I think it is easy to do this, but always failed.

error[E0507]: cannot move out of `root.left.0` which is behind a mutable reference
   --> src/main.rs:120:33
    |
120 |             Some(root) => match root.left {
    |                                 ^^^^^^^^^ help: consider borrowing here: `&root.left`
121 |                 Some(left) => {
    |                      ----
    |                      |
    |                      data moved here
    |                      move occurs because `left` has type `Box<Node>`, which does not implement the `Copy` trait

For more information about this error, try `rustc --explain E0507`.

playground

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can use std::mem::take, which allows taking things out of a mutable reference to them (replacing the pointed value with the default value of that type). That is, your function left can be rewritten:

use std::mem::take;

fn left(&mut self) -> Result<(), Error> {
    let root = self.root.as_mut().ok_or(Error::EmptyTree)?;
    let left = take(&mut root.left).ok_or(Error::NotFound)?;
    *root = left;
    Ok(())
}

Edit: turns out there is a method that does exactly that. I’ll leave my first snippet so that you understand what happens, but the following is probably more suitable in real code.

fn left(&mut self) -> Result<(), Error> {
    let root = self.root.as_mut().ok_or(Error::EmptyTree)?;
    let left = root.left.take().ok_or(Error::NotFound)?;
    *root = left;
    Ok(())
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading