簡體   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