【问题标题】:wrestling with borrow checker与借用检查器搏斗
【发布时间】:2015-07-01 05:55:51
【问题描述】:

我是 Rust 的新手。作为一项学习练习,我正在尝试制作一个基本的二叉树。这是我到目前为止所拥有的:

fn main() {
    let data = vec![6,1,2,3,4,5];

    let mut root = Node::<i32> { value: data[0], left: None, right: None };

    for val in data {
        createAndInsert::<i32>(&root, val);
    }
    println!("Root value: {}", root.value); 
}

fn createAndInsert<T: PartialOrd>(mut root: &Node<T>, value: T) {
    let mut n = Node::<T> { value: value, left: None, right: None };
    insert::<T>(&root, &n);
}

fn insert<T: PartialOrd>(mut curr: &Node<T>, new: &Node<T>) {
    if new.value > curr.value {
        match curr.right {
            Some(ref n) => insert(n, new),
            None => curr.right = Some(Box::new(*new))
        }
    } else {
        match curr.left {
            Some(ref n) => insert(n, new),
            None => curr.left = Some(Box::new(*new))
        }
    }
}

struct Node<T: PartialOrd> {
    value: T,
    left: Option<Box<Node<T>>>,
    right: Option<Box<Node<T>>>,
}

我得到的编译器错误:

test.rs:21:48: 21:52 error: cannot move out of borrowed content
test.rs:21             None => curr.right = Some(Box::new(*new))
                                                          ^~~~
test.rs:26:47: 26:51 error: cannot move out of borrowed content
test.rs:26             None => curr.left = Some(Box::new(*new))
                                                         ^~~~
test.rs:21:21: 21:54 error: cannot assign to immutable field `curr.right`
test.rs:21             None => curr.right = Some(Box::new(*new))
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.rs:26:21: 26:53 error: cannot assign to immutable field `curr.left`
test.rs:26             None => curr.left = Some(Box::new(*new))
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 4 previous errors

我已经被所有的 refs 和 muts 以及 &'s 和 *'s 缠住了,我不知道如何摆脱。我哪里错了?

【问题讨论】:

标签: rust


【解决方案1】:

你有两个问题:

  • 无法脱离借用的上下文:请参阅 Cannot move out of borrowed content when borrowing a generic type 了解说明。

  • 不能分配给不可变字段:你只有一个&amp;Node&lt;T&gt;;要修改Node,您需要&amp;mut Node&lt;T&gt;。模式中的mut curr 只是使binding 可变,这意味着您可以为curr 分配一个新值。但是,您不能修改 curr 所指内容的内容。在整个代码中传播&amp;-to-&amp;mut 转换,它就会起作用。

【讨论】:

    【解决方案2】:

    由于您是 Rust 新手,看看我会如何编写它可能会有所帮助:

    struct Node<T> {
        value: T,
        left: Option<Box<Node<T>>>,
        right: Option<Box<Node<T>>>,
    }
    
    impl<T> Node<T> {
        fn new(x: T) -> Node<T> {
            Node { value: x, left: None, right: None }
        }
        fn boxed(x: T) -> Box<Node<T>> {
            Box::new(Node::new(x))
        }
    }
    
    fn insert<T: PartialOrd>(root: &mut Option<Box<Node<T>>>, new: Box<Node<T>>) {
        if let Some(ref mut rbx) = *root {
            if new.value < rbx.value {
                insert(&mut rbx.left, new);
            } else {
                insert(&mut rbx.right, new);
            }
        } else {
            *root = Some(new);
        }
    }
    
    fn main() {
        let data = vec![6,1,2,3,4,5];
        let mut root = None;
        for val in data {
            insert(&mut root, Node::boxed(val));
        }
        println!("Root value: {}", root.unwrap().value); 
    }
    

    我意识到这更像是一种练习,但请记住,这种数据结构不应增长到超过特定树深度,否则当节点被递归释放时,它可能会导致堆栈溢出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多