2013-07-08 14 views
8

Referans için, Rust 0.7 kullanıyorum.Sahip olunan bir işaretçi nasıl taşınır

Bağlı bir bağlantı listesi kullanarak yığın uygulaması oluşturmaya çalışıyorum ve sorun yaşıyorum. Ben rustc stack.rs çalıştığınızda

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

aşağıdaki hatayı alıyorum:

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

Ben bu baş edebilen ya da ne ben farklı yapabileceği buna izin nasıl bilmiyorum. Yönetilen işaretçileri kullanmadan bu veri yapısını oluşturabilmem gerektiği gibi görünüyor, ancak bu tür şeylerle ilgili pek çok belge görmedim. .

Ben Link(item, *self) implies a move olduğu gibi, bunun dışında yeni bir şey inşa içerir düşünüyorum öz (dan
+1

'(Kesme'yi kendini) kuyruk = std :: util :: yerini izin Kabul cevap gibi' Zinciri 'üzerindeki özellik uygulamak gerekir, ancak böyle bir şey kullanarak fikir muhafaza edebilir; std :: util :: replace (kendiliğinden, Link (item, ~ tail)); 'replace 've' swap' işlevleri, sahip olunan veri yapılarıyla çalışırken önemli araçlardır. – u0b34a0f6ae

cevap

5

Ya ataması Bu demektir ki kendini, kullanışsız hale gelmesi yeni Link inşa sürecinde çünkü:

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

Doğru ™ muhtemelen en iyi this example in the stdlib içinde yaptıklarından tarafından belgelenmiştir. Bu bir iki kat bağlantılı liste, ve o yönetilen, ancak değişken, ve ben özgür kopya umuyorum. çok da list of useful container types var.

ben verilerinizin bu değişmez versiyonunu almayı başardı Bununla birlikte, yapı çalışması.

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

Oldukça iyi. Bence pop'u geri döndürdüyseniz (Self, Option ) daha iyi olurdu ama bu doğru yönde büyük bir adım. Çok teşekkürler! –

+0

Öneri alındı. – tehgeekmeister

+3

Bu aşamada, seçeneğin her iki sonucu da içerdiğinden emin olabilirsiniz - bunlar her ikisinden biri veya ikisi de yoktur. –

İlgili konular