2013-07-08 2 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); 
             ^~~~~~ 

私はこれを克服することができる方法や、私がこれを許可するように異なって何ができるかわかりません。管理されたポインタを使用せずにこのデータ構造を作成できるはずですが、私はこのようなことについて多くのドキュメントを見ていません。

+1

'(、休憩を自己)尾=のstd :: utilの::置き換えてみましょうあなたは受け入れ答えのような'チェーン '上の形質を実装する必要がありますが、あなたのようなものを使用して、あなたのアイデアを保持することができます。 std :: util :: replace(self、Link(item、〜tail)); '' replace'と 'swap'関数は所有しているデータ構造を扱う際に重要なツールです。 – u0b34a0f6ae

答えて

5

私はLink(item, *self)implies a moveの場合のように、そこから新しいものを構築含ん考える自己のいずれかからの割り当て(これは新しい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あります。

Iあなたのデータのこの不変のバージョンを取得できましたしかし、構造的な作業。

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

この段階では、オプションに両方の結果が含まれるようにすることもできます。これらのオプションは、常にどちらか一方または両方のどちらでもありません。 –

関連する問題