2014-11-29 12 views
9

Các gỉ bằng ví dụ hướng dẫn cho thấy đoạn mã sau here cho một loạt fibonacci với lặp:mem :: thay thế trong Rust

fn next(&mut self) -> Option<u32> { 
    let new_next = self.curr + self.next; 
    let new_curr = mem::replace(&mut self.next, new_next); 

    // 'Some' is always returned, this is an infinite value generator 
    Some(mem::replace(&mut self.curr, new_curr)) 
} 

Tôi muốn hiểu được những lợi thế của việc này là gì, so với trực quan nhất (nếu bạn đến từ các ngôn ngữ khác):

fn next(&mut self) -> Option<u32> { 
    let tmp = self.next; 
    self.next = self.curr + self.next; 
    self.curr = tmp; 
    Some(self.curr) 
} 

Trả lời

10

Không phải lúc nào cũng có thể viết mã trực tiếp, do quyền sở hữu của Rust. Nếu self.next lưu trữ loại không phải là Copy (ví dụ: Vec<T> đối với bất kỳ loại T) thì let tmp = self.next; lấy giá trị đó ra khỏi self theo giá trị, nghĩa là di chuyển quyền sở hữu, vì vậy không nên sử dụng được nguồn. Nhưng nguồn nằm phía sau tham chiếu và tham chiếu phải luôn trỏ đến dữ liệu hợp lệ, do đó trình biên dịch không thể cho phép di chuyển ra khỏi &mut: bạn gặp lỗi như cannot move out of dereference of `&mut`-pointer.

replace giải quyết các vấn đề này qua mã unsafe, bằng cách đảm bảo rằng bất kỳ việc vô hiệu nào được hoàn toàn hợp lệ vào thời điểm replace trả về.

Bạn có thể thấy this answer để biết thêm về động thái nói chung, và this question cho một vấn đề có liên quan về một hàm swap (replaceimplemented sử dụng the standard library's swap nội bộ).

+0

Cảm ơn câu trả lời. Nó rất rõ ràng. Tôi phải nói rằng mặc dù tôi đã theo dõi hầu hết các hướng dẫn viên Rust, nhưng tôi vẫn chưa rõ về những thứ nhất định. Nói cách khác, tôi có thể đọc/thay đổi một chương trình nhưng tôi không chắc mình sẽ đưa ra quyết định đúng nếu tôi phải làm nó từ đầu. Bạn có thể đề xuất một số hướng dẫn khác cho việc này không. – Hernan

+0

@Hernan, có [Rust by Example] (http://rustbyexample.com/) nhưng tôi không chắc đó có phải là những gì bạn đang tìm kiếm hay không. Để "đưa ra quyết định đúng", các lỗi biên dịch về mặt lý thuyết hướng dẫn bạn đúng hướng, có một số nguyên tắc chung như "không thể di chuyển ra khỏi ..." gợi ý sử dụng tham chiếu hoặc sử dụng hàm như 'replace' hoặc' swap', " không thể mượn ... "gợi ý sử dụng nhiều' {} 'phạm vi. (Với thực hành bạn có thể dự đoán khi trình biên dịch phàn nàn và sử dụng sửa chữa ngay lập tức, nhưng hộp thoại nội bộ của tôi vẫn là bản chất "trình biên dịch sẽ phàn nàn về điều này".) – huon

+0

Tôi nên nói "quyết định đúng" trong thiết kế. Tôi sẽ tiếp tục đọc và viết mã. – Hernan

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