2015-01-26 24 views
65

Tôi không hiểu lỗi cannot move out of borrowed content. Tôi đã nhận được nó nhiều lần và tôi đã luôn luôn giải quyết nó, nhưng tôi chưa bao giờ hiểu tại sao.Không thể di chuyển ra khỏi nội dung đã mượn

Ví dụ:

for line in self.xslg_file.iter() { 
    self.buffer.clear(); 

    for current_char in line.into_bytes().iter() { 
     self.buffer.push(*current_char as char); 
    } 

    println!("{}", line); 
} 

tạo ra lỗi:

error[E0507]: cannot move out of borrowed content 
    --> src/main.rs:31:33 
    | 
31 |    for current_char in line.into_bytes().iter() { 
    |         ^^^^ cannot move out of borrowed content 

Tôi giải quyết nó bằng cách nhân bản line:

for current_char in line.clone().into_bytes().iter() { 

Tôi không hiểu các lỗi ngay cả sau khi đọc khác các bài đăng như:

nguồn gốc của loại hình báo lỗi là gì?

+1

Bạn đã nhìn [câu hỏi như thế này] (http://stackoverflow.com/q/28034646/1256624)? (Btw, strings cung cấp phương thức '.bytes()'.) – huon

+0

Vâng, tôi nhìn vào nó, nhưng không hiểu :(Và chuỗi của tôi là một chuỗi :: string :: String, theo tài liệu, không có .bytes() Phương thức – Peekmo

+3

Nó được gọi là '.as_bytes()' – bluss

Trả lời

61

Hãy nhìn vào chữ ký cho into_bytes:

fn into_bytes(self) -> Vec<u8> 

này có self, không phải là một tài liệu tham khảo để tự (&self). Điều đó có nghĩa là self sẽ là được tiêu thụ và sẽ không khả dụng sau cuộc gọi. Ở vị trí của nó, bạn nhận được Vec<u8>. Tiền tố into_ là cách phổ biến để biểu thị các phương pháp như thế này.

Tôi không biết chính xác phương thức iter() của bạn trả về, nhưng tôi đoán đó là một trình lặp trên &String, nghĩa là nó trả về tham chiếu đến String nhưng không cung cấp cho bạn quyền sở hữu chúng. Điều đó có nghĩa là bạn không thể gọi phương thức tiêu thụ giá trị.

Như bạn đã tìm thấy, một giải pháp là sử dụng clone. Điều này tạo ra một đối tượng trùng lặp mà bạn tự làm và có thể gọi into_bytes vào. Như những người nhận xét khác đề cập đến, bạn cũng có thể sử dụng as_bytes mất &self, vì vậy nó sẽ hoạt động trên một giá trị được vay. Mà một trong những bạn nên sử dụng phụ thuộc vào mục tiêu cuối cùng của bạn cho những gì bạn làm với con trỏ.

Trong bức tranh lớn hơn, tất cả điều này phải làm với khái niệm về quyền sở hữu. Một số hoạt động phụ thuộc vào việc sở hữu mục và các hoạt động khác có thể lấy đi bằng cách mượn đối tượng (có lẽ là một cách rõ ràng). Một tài liệu tham khảo (&foo) không cấp quyền sở hữu, nó chỉ là một khoản vay.

Why is it interesting to use self instead of &self in a function's arguments?

Chuyển quyền sở hữu là một khái niệm hữu ích nói chung - khi tôi làm xong điều gì đó, người khác có thể có nó. Trong Rust, đó là một cách để có hiệu quả hơn. Tôi có thể tránh phân bổ một bản sao, cung cấp cho bạn một bản sao, sau đó vứt bỏ bản sao của tôi. Quyền sở hữu cũng là trạng thái dễ chấp nhận nhất; nếu tôi sở hữu một vật thể tôi có thể làm với nó như tôi muốn.


Dưới đây là đoạn code mà tôi tạo ra để thử nghiệm với:

struct IteratorOfStringReference<'a>(&'a String); 

impl<'a> Iterator for IteratorOfStringReference<'a> { 
    type Item = &'a String; 

    fn next(&mut self) -> Option<Self::Item> { 
     None 
    } 
} 

struct FileLikeThing { 
    string: String, 
} 

impl FileLikeThing { 
    fn iter(&self) -> IteratorOfStringReference { 
     IteratorOfStringReference(&self.string) 
    } 
} 

struct Dummy { 
    xslg_file: FileLikeThing, 
    buffer: String, 
} 

impl Dummy { 
    fn dummy(&mut self) { 
     for line in self.xslg_file.iter() { 
      self.buffer.clear(); 

      for current_char in line.into_bytes().iter() { 
       self.buffer.push(*current_char as char); 
      } 

      println!("{}", line); 
     } 
    } 
} 

fn main() {} 
+2

Cảm ơn bạn, tất cả đã rõ ràng! :) – Peekmo

+1

Chỉ là một câu hỏi. Tại sao nó thú vị để sử dụng (self) thay vì (& self) trong một hàm args? – Peekmo

+4

Chuyển quyền sở hữu là một khái niệm hữu ích nói chung - khi tôi làm xong điều gì đó, một người khác có thể có nó. Trong Rust, đó là một cách để có hiệu quả hơn (như trái ngược với việc phân bổ một bản sao, cung cấp cho bạn một bản sao, sau đó vứt bỏ bản sao của tôi). Quyền sở hữu cũng là trạng thái dễ chấp nhận nhất; nếu tôi sở hữu một vật thể tôi có thể làm với nó như tôi muốn. – Shepmaster

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