2015-07-01 19 views
3

我是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 

我有我自己的所有裁判和MutS的和&糾結的和*'我不確定如何離開。我哪裏錯了?

+0

[借用泛型時無法移出借用內容](http://stackoverflow.com/questions/28595075/cannot-move-out-of-borrowed-content-when-borrowing-a-通用型) –

回答

5

你有兩個問題:

  • 不能遷出借來的背景:見Cannot move out of borrowed content when borrowing a generic type一個解釋。

  • 無法分配給不可變字段:您只有&Node<T>;要修改Node您需要一個&mut Node<T>mut curr只能使綁定可變,這意味着您可以將新值分配給curr。但是,您不能修改curr所指的內容。在整個代碼中傳播&&mut的轉換,它將起作用。

3

既然你是新生鏽可能會有所幫助,看我怎麼會寫它:

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

我意識到,這更多的是一種鍛鍊,但要記住,這種數據結構不應超過某個樹深度,否則會導致堆棧在節點被遞歸解除分配時溢出。