2013-07-08 79 views
8

僅供參考,我使用的是Rust 0.7。如何移動指針

我想創建一個使用擁有鏈表的堆棧實現,我遇到了麻煩。

trait Stack<T> { 
    fn push(&mut self, item : T); 
    fn pop(&mut self) -> Option<T>; 
} 

enum Chain<T> { 
    Link(T, ~Chain<T>), 
    Break 
} 

impl<T> Stack<T> for ~Chain<T> { 
    fn push(&mut self, item : T) { 
     *self = ~Link(item, *self); 
    } 
    fn pop(&mut self) -> Option<T> { 
     None 
    } 
} 

當我嘗試rustc stack.rs我得到以下錯誤:

stack.rs:13:28: 13:34 error: cannot move out of dereference of & pointer 
stack.rs:13   *self = ~Link(item, *self); 
             ^~~~~~ 

我不知道我是怎麼克服這個還是我能做什麼不同,讓這一點。看起來我應該能夠創建這個數據結構而不使用託管指針,但是我還沒有看到很多這方面的文檔。 。

從自我(我認爲包括建設一個新的東西出來,如在 Link(item, *self) implies a move的情況下
+1

你應該實現對連鎖''喜歡接受的答案的特質,但你可以通過使用類似保留您的想法'讓尾部=的std :: UTIL ::代替(個體經營,斷裂); std :: util :: replace(self,Link(item,〜tail));'當使用擁有的數據結構時,'replace'和'swap'函數是重要的工具。 – u0b34a0f6ae

回答

5

無論是分配這意味着,在構建新的Link,自我變得不可用,過程,原因是:

"After a value has been moved, it can no longer be used from the source location and will not be destroyed there."

一條正確的路™是由什麼在this example in the stdlib做可能是最好的證明。這是一個雙向鏈表,它是管理,但它是可變的,我希望自由拷貝。還有list of useful container types了。

我設法獲得了這個不可變數據的版本結構工作,但是。

trait Stack<T> { 
    fn push(self, item : T) -> Self; 
    fn pop(self)   -> Option<(T, Self)>; 
    fn new()    -> Self; 
} 

#[deriving(Eq, ToStr)] 
enum Chain<T> { 
    Link(T, ~Chain<T>), 
    Break 
} 

impl<T> Stack<T> for Chain<T> { 
    fn push(self, item : T) -> Chain<T> { 
     Link(item, ~self) 
    } 
    fn pop(self)   -> Option<(T, Chain<T>)> { 
     match self { 
      Link(item, ~new_self) => Some((item, new_self)), 
      Break     => None 
     } 
    } 
    fn new()    -> Chain<T> { 
     Break 
    } 
} 

fn main() { 
    let b : ~Chain<int> = ~Stack::new(); 
    println(b.push(1).push(2).push(3).to_str()); 
} 
+1

這很不錯。我認爲如果你改變流行音樂迴歸(Self,Option ),那會更好,但這是向正確方向邁出的巨大一步。非常感謝! –

+0

已採取建議。 – tehgeekmeister

+3

在這個階段,你也可以讓選項包含兩個結果 - 它們總是或者都是一個或者兩個都沒有。 –