2013-07-08 33 views
8

Để tham khảo, tôi đang sử dụng Rust 0.7.Cách di chuyển con trỏ thuộc sở hữu

Tôi đang cố gắng tạo triển khai ngăn xếp bằng danh sách được liên kết thuộc sở hữu và tôi đang gặp sự cố.

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

Khi tôi cố gắng rustc stack.rs tôi nhận được lỗi sau:

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

Tôi không biết làm thế nào tôi có thể khắc phục điều này hoặc những gì tôi có thể làm cách khác nhau để cho phép điều này. Có vẻ như tôi sẽ có thể tạo cấu trúc dữ liệu này mà không cần sử dụng con trỏ được quản lý, nhưng tôi chưa thấy nhiều tài liệu về loại điều này. .

+1

bạn nên thực hiện các đặc điểm trên 'Chuỗi ' như câu trả lời được chấp nhận, nhưng bạn có thể giữ lại ý tưởng của bạn bằng cách sử dụng một cái gì đó như 'hãy đuôi = std :: util :: replace (tự, Break); std :: util :: replace (self, Link (item, ~ tail)); 'Các hàm' replace' và 'swap' là các công cụ quan trọng khi làm việc với các datastructures sở hữu. – u0b34a0f6ae

Trả lời

5

Hoặc chuyển nhượng từ ngã (mà tôi nghĩ bao gồm xây dựng một điều mới ra khỏi nó, như trong trường hợp của Link(item, *self)implies a move này có nghĩa là trong quá trình xây dựng mới Link rằng tự trở nên không sử dụng được, bởi vì:

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

The Right Way ™ có lẽ là tốt nhất ghi nhận bởi những gì đang thực hiện trong this example in the stdlib. đó là một danh sách gấp đôi liên kết, và nó được quản lý, nhưng nó có thể thay đổi, và tôi hy vọng sao chép miễn phí. Ngoài ra còn có list of useful container types, quá.

tôi đã quản lý để có được phiên bản dữ liệu bất biến này cấu trúc làm việc, tuy nhiên.

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

Điều đó khá tốt. Tôi nghĩ nếu bạn thay đổi pop để trở lại (Self, Option ) nó sẽ là tốt hơn, nhưng đó là một bước tiến lớn trong đúng hướng. Cảm ơn rất nhiều! –

+0

Đề xuất được thực hiện. – tehgeekmeister

+3

Ở giai đoạn này, bạn cũng có thể làm cho tùy chọn chứa cả hai kết quả - chúng luôn là cả hai hoặc không có cả hai. –

Các vấn đề liên quan