繁体   English   中英

从 rust 中的 struct 返回一个值 T

[英]return a value T from struct in rust

我正在尝试在 rust 中实现双链接二叉树,当我尝试实现函数以从节点返回特定值以在包含要删除的值的节点中替换它时遇到了一些问题。 这是我的代码:

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();
}

这是错误:

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

我如何返回值或克隆它?

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();
}

当您将 find_left_none 的返回值定义为不是引用类型的 T 时,您必须在从方法返回之前克隆该值

这里的问题是您试图销毁节点的一部分,但您只有对它的可变引用。 self.value必须能够被移动(这意味着整个结构现在“死了”(如果它的一部分移动了,整个事情都消失了),因此你需要将self传递给函数而不是&mut self来做到这一点) 或value字段必须能够被复制( Copy trait,以及对你可以持有的内容的限制)。

那么,当您返回内容时,您是否试图破坏当前节点? 根据上下文,可能不是,您似乎希望返回节点的value ,因此T是返回值。 所以你要么需要显式地std::clone它,要么你需要返回对它的引用,这意味着生命周期。

我建议通读Learn Rust With Entirely Too Many Linked Lists以获得灵感和帮助。 特别是第一章Pop章节,以及Iter 中的生命周期章节

对于您的程序,请更改以下内容:

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> {

我希望这有助于解释您还需要什么以及为什么。

暂无
暂无

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

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