简体   繁体   中英

return a value T from struct in rust

I am trying to implement a double linked binary tree in rust, and I have some problems when I try to implement functions to return a specific value from a node to replace it in a node that contain the value that I want to delete. This is my code :

use std::{borrow::BorrowMut, cell::RefCell, fmt::Debug, rc::Rc};

#[derive(Debug)]
struct Tree<T> {
    root: Link<T>
}

type Link<T> = Option<Rc<RefCell<Node<T>>>>;

#[derive(Debug)]
struct Node<T> {
    value: T,
    prev: Link<T>,
    right: Link<T>,
    left: Link<T>
}

impl<T: Ord+ Debug> Node<T> {
    fn new(value: T, prev: Link<T>, right: Link<T>, left: Link<T>) -> Self {
        Node {
            value: value,
            prev: prev,
            right: right,
            left: left
        }
    }

    //fn get_prev(&mut self, value: &T) -> Link<T> {
        //if value > &self.value {
            //return self.right.clone();
        //}else {
            //return self.left.clone();
        //}
    //}

    fn insert_value(&mut self, value: T, prev: Link<T>) {
        if value == self.value { return; }
        if value > self.value {
            if self.right.is_none() {
                let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
                self.right = node;
            }else {
                let mut prev_current = self.right.clone();
                self.right.as_mut().map(|node| {
                    (**node).borrow_mut().insert_value(value, prev_current);
                });
            }
        }else {
            if self.left.is_none() {
                let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
                self.left = node;
            }else {
                let mut prev_current = self.left.clone();
                self.left.as_mut().map(|node| {
                    (**node).borrow_mut().insert_value(value, prev_current);
                });
            }
        }
    }

    fn print_prev(&self){
        println!("{:?}", self.value);
    }

    fn print_tree(&self) {
        println!("------");
        println!("{:?}", self.value);
        if (!self.prev.is_none()){
            self.prev.as_ref().map(|node| {
                (**node).borrow().print_prev();
            });
        }
        if (!self.right.is_none()) {
            self.right.as_ref().map(|node| {
                (**node).borrow().print_tree();
            });
        }
        if (!self.left.is_none()) {
            self.left.as_ref().map(|node| {
                (**node).borrow().print_tree();
            });
        }
    }

    fn set_prev_none(&mut self, value: &T) {
        if value > &self.value {
            self.right = None;
        }else {
            self.left = None;
        }
    }

    fn set_prev_node(&mut self, value: &T, node: Link<T>){
        if value > &self.value {
            self.right = node;
        }else {
            self.left = node;
        }
    }

    fn find_left_none(&mut self) -> T {
        if (self.left.is_none() && self.right.is_none()) {
            let mut value = &self.value;
            self.prev.as_mut().map(|node| {
                (**node).borrow_mut().set_prev_none(value);
            });
            return self.value;
        }else {
            return (**self.left.as_mut().unwrap().borrow_mut()).borrow_mut().find_left_none();
        }
    }

    fn delete_node(&mut self, value: T) {
        if self.value == value {
            if self.right.is_none() && self.left.is_none() {
                let mut temp_val = &self.value;
                self.prev.as_mut().map(|node| {
                    (**node).borrow_mut().set_prev_none(temp_val);
                }); 
            }else if(self.right.is_none() ^ self.left.is_none()) {
                let mut prev_temp = self.prev.clone(); 
                let mut temp_val = &self.value;
                let mut temp_next = None;
                if self.right.is_none(){
                    temp_next = self.right.clone();
                    self.right.as_mut().map(|node| {
                        (**node).borrow_mut().prev = prev_temp.clone();
                    });
                }else {
                    temp_next = self.left.clone();
                    self.left.as_mut().map(|node| {
                        (**node).borrow_mut().prev = prev_temp.clone();
                    });
                }
                prev_temp.as_mut().map(|node| {
                    (**node).borrow_mut().set_prev_node(temp_val, temp_next);
                });
            }else {
                let mut val: Option<T> = None;
                self.right.as_mut().map(|node| {
                    val = Some((**node).borrow_mut().find_left_none());
                });
                self.value = val.unwrap();
            }
        }else {
            if value > self.value {
                self.right.as_mut().map(|node| {
                    (**node).borrow_mut().delete_node(value);
                });
            }else {
                self.left.as_mut().map(|node| {
                    (**node).borrow_mut().delete_node(value);
                });
            }
        }
    }
}

impl<T: Ord+Debug> Tree<T> {
    fn new() -> Self {
        Tree {
            root: None
        }
    }

    fn insert_value(&mut self, value: T) {
        if self.root.is_none() {
            self.root = Some(Rc::new(RefCell::new(Node::new(value, None, None, None))));
        }else {
            let mut prev = self.root.clone();
            self.root.as_mut().map(|node| {
                (**node).borrow_mut().insert_value(value, prev);
            });
        }
    }

    fn delete_node(&mut self, value: T){
        if !self.root.is_none() {
            self.root.as_mut().map(|node| {
                (**node).borrow_mut().delete_node(value);
            });
        }
    }

    fn print_tree(&self) {
        if !self.root.is_none() {
            self.root.as_ref().map(|node| {
                (**node).borrow().print_tree();
            });
        }else {
            println!("empty");
        }
    }
}

fn main() {
    let mut tree = Tree::new();
    tree.insert_value(5);
    tree.insert_value(1);
    tree.insert_value(7);
    tree.insert_value(4);
    tree.insert_value(5);
    tree.print_tree();
}

This is the error:

error[E0507]: cannot move out of `self.value` which is behind a mutable reference
   --> .\tree-double.rs:107:20
    |
107 |             return self.value;
    |                    ^^^^^^^^^^ move occurs because `self.value` has type `T`, which does not implement the `Copy` trait

How I can return the value or clone it?

use std::{borrow::BorrowMut, cell::RefCell, fmt::Debug, rc::Rc};

#[derive(Debug)]
struct Tree<T: Clone> {
    root: Link<T>,
}

type Link<T> = Option<Rc<RefCell<Node<T>>>>;

// you can restrict T to be Cloneable
#[derive(Debug)]
struct Node<T: Clone> {
    value: T,
    prev: Link<T>,
    right: Link<T>,
    left: Link<T>,
}

impl<T: Ord + Debug + Clone> Node<T> {
    fn new(value: T, prev: Link<T>, right: Link<T>, left: Link<T>) -> Self {
        Node {
            value: value,
            prev: prev,
            right: right,
            left: left,
        }
    }

    //fn get_prev(&mut self, value: &T) -> Link<T> {
    //if value > &self.value {
    //return self.right.clone();
    //}else {
    //return self.left.clone();
    //}
    //}

    fn insert_value(&mut self, value: T, prev: Link<T>) {
        if value == self.value {
            return;
        }
        if value > self.value {
            if self.right.is_none() {
                let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
                self.right = node;
            } else {
                let mut prev_current = self.right.clone();
                self.right.as_mut().map(|node| {
                    (**node).borrow_mut().insert_value(value, prev_current);
                });
            }
        } else {
            if self.left.is_none() {
                let mut node = Some(Rc::new(RefCell::new(Node::new(value, prev, None, None))));
                self.left = node;
            } else {
                let mut prev_current = self.left.clone();
                self.left.as_mut().map(|node| {
                    (**node).borrow_mut().insert_value(value, prev_current);
                });
            }
        }
    }

    fn print_prev(&self) {
        println!("{:?}", self.value);
    }

    fn print_tree(&self) {
        println!("------");
        println!("{:?}", self.value);
        if (!self.prev.is_none()) {
            self.prev.as_ref().map(|node| {
                (**node).borrow().print_prev();
            });
        }
        if (!self.right.is_none()) {
            self.right.as_ref().map(|node| {
                (**node).borrow().print_tree();
            });
        }
        if (!self.left.is_none()) {
            self.left.as_ref().map(|node| {
                (**node).borrow().print_tree();
            });
        }
    }

    fn set_prev_none(&mut self, value: &T) {
        if value > &self.value {
            self.right = None;
        } else {
            self.left = None;
        }
    }

    fn set_prev_node(&mut self, value: &T, node: Link<T>) {
        if value > &self.value {
            self.right = node;
        } else {
            self.left = node;
        }
    }

    fn find_left_none(&mut self) -> T {
        if (self.left.is_none() && self.right.is_none()) {
            let mut value = &self.value;
            self.prev.as_mut().map(|node| {
                (**node).borrow_mut().set_prev_none(value);
            });
            // you need clone the value before return, otherwise T must implement Copy trait, because 
            return self.value.clone();
        } else {
            return (**self.left.as_mut().unwrap().borrow_mut())
                .borrow_mut()
                .find_left_none();
        }
    }

    fn delete_node(&mut self, value: T) {
        if self.value == value {
            if self.right.is_none() && self.left.is_none() {
                let mut temp_val = &self.value;
                self.prev.as_mut().map(|node| {
                    (**node).borrow_mut().set_prev_none(temp_val);
                });
            } else if (self.right.is_none() ^ self.left.is_none()) {
                let mut prev_temp = self.prev.clone();
                let mut temp_val = &self.value;
                let mut temp_next = None;
                if self.right.is_none() {
                    temp_next = self.right.clone();
                    self.right.as_mut().map(|node| {
                        (**node).borrow_mut().prev = prev_temp.clone();
                    });
                } else {
                    temp_next = self.left.clone();
                    self.left.as_mut().map(|node| {
                        (**node).borrow_mut().prev = prev_temp.clone();
                    });
                }
                prev_temp.as_mut().map(|node| {
                    (**node).borrow_mut().set_prev_node(temp_val, temp_next);
                });
            } else {
                let mut val: Option<T> = None;
                self.right.as_mut().map(|node| {
                    val = Some((**node).borrow_mut().find_left_none());
                });
                self.value = val.unwrap();
            }
        } else {
            if value > self.value {
                self.right.as_mut().map(|node| {
                    (**node).borrow_mut().delete_node(value);
                });
            } else {
                self.left.as_mut().map(|node| {
                    (**node).borrow_mut().delete_node(value);
                });
            }
        }
    }
}

impl<T: Ord + Debug + Clone> Tree<T> {
    fn new() -> Self {
        Tree { root: None }
    }

    fn insert_value(&mut self, value: T) {
        if self.root.is_none() {
            self.root = Some(Rc::new(RefCell::new(Node::new(value, None, None, None))));
        } else {
            let mut prev = self.root.clone();
            self.root.as_mut().map(|node| {
                (**node).borrow_mut().insert_value(value, prev);
            });
        }
    }

    fn delete_node(&mut self, value: T) {
        if !self.root.is_none() {
            self.root.as_mut().map(|node| {
                (**node).borrow_mut().delete_node(value);
            });
        }
    }

    fn print_tree(&self) {
        if !self.root.is_none() {
            self.root.as_ref().map(|node| {
                (**node).borrow().print_tree();
            });
        } else {
            println!("empty");
        }
    }
}

fn main() {
    let mut tree = Tree::new();
    tree.insert_value(5);
    tree.insert_value(1);
    tree.insert_value(7);
    tree.insert_value(4);
    tree.insert_value(5);
    tree.print_tree();
}

as you define the return value of find_left_none to T which is not a reference type, you have to clone the value before return from the method

The problem here is that you're trying to destroy part of the node, but you only have a mutable reference to it. Either self.value must be able to be moved (which means the entire struct is now "dead" (if part of it moves, the whole thing is gone) and thus you need to pass self to the function not &mut self to do that) or the value field must be able to be copied ( Copy trait, and a constraint on what you can hold).

So are you trying to destroy the current node when you return the contents? By context, probably not, it seems like you want the value of the node returned, hence T being the return value. So you either need to explicitly std::clone it, or you need to return a reference to it, which means lifetimes.

I suggest reading through Learn Rust With Entirely Too Many Linked Lists for inspiration and assistance. In particular, the firstPop chapter, as well as the lifetimes one in Iter

For your program, change the following:

impl<T: Clone + Ord + Debug> Node<T> {

// Snip

    fn find_left_none(&mut self) -> T {
        if (self.left.is_none() && self.right.is_none()) {
            let mut value = &self.value;
            self.prev.as_mut().map(|node| {
                (**node).borrow_mut().set_prev_none(value);
            });
            return self.value.clone();
        }else {
            return (**self.left.as_mut().unwrap().borrow_mut()).borrow_mut().find_left_none();
        }
    }

// Snip

impl<T: Clone + Ord+Debug> Tree<T> {

I hope that helps explain what else you needed and why.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM