简体   繁体   English

从 rust 中的 struct 返回一个值 T

[英]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.我正在尝试在 rust 中实现双链接二叉树,当我尝试实现函数以从节点返回特定值以在包含要删除的值的节点中替换它时遇到了一些问题。 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当您将 find_left_none 的返回值定义为不是引用类型的 T 时,您必须在从方法返回之前克隆该值

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). self.value必须能够被移动(这意味着整个结构现在“死了”(如果它的一部分移动了,整个事情都消失了),因此你需要将self传递给函数而不是&mut self来做到这一点) 或value字段必须能够被复制( Copy trait,以及对你可以持有的内容的限制)。

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.根据上下文,可能不是,您似乎希望返回节点的value ,因此T是返回值。 So you either need to explicitly std::clone it, or you need to return a reference to it, which means lifetimes.所以你要么需要显式地std::clone它,要么你需要返回对它的引用,这意味着生命周期。

I suggest reading through Learn Rust With Entirely Too Many Linked Lists for inspiration and assistance.我建议通读Learn Rust With Entirely Too Many Linked Lists以获得灵感和帮助。 In particular, the firstPop chapter, as well as the lifetimes one in Iter特别是第一章Pop章节,以及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.我希望这有助于解释您还需要什么以及为什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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