2013-07-08 75 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

在这个阶段,你也可以让选项包含两个结果 - 它们总是或者都是一个或者两个都没有。 –