2015-01-26 12 views
65

Nie rozumiem błędu cannot move out of borrowed content. Otrzymałem go wiele razy i zawsze go rozwiązałem, ale nigdy nie rozumiałem, dlaczego.Nie można przenieść z pożyczonej treści

Na przykład:

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

produkuje błąd:

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 

Rozwiązałem go przez klonowanie line:

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

Nie rozumiem błąd nawet po przeczytaniu innych posty takie jak:

Jakie jest pochodzenie tego rodzaju błąd? wygląd

+1

Pan spojrzał na pytania, jak to [] (http://stackoverflow.com/q/28034646/1256624)? (Btw, łańcuchy oferują metodę '.bytes()'.) – huon

+0

Tak, zaglądałem do niej, ale nie rozumiałem :(A mój ciąg to ciąg :: string :: String, zgodnie z dokumentacją, nie ma .bytes() metoda – Peekmo

+3

Nazywa się '.as_bytes()' – bluss

Odpowiedz

61

Miejmy na podpis dla into_bytes:

fn into_bytes(self) -> Vec<u8> 

Dzieje self, a nie odniesienie do siebie (&self). Oznacza to, że self będzie spożytkowany i nie będzie dostępny po wywołaniu. W jego miejsce otrzymujesz numer Vec<u8>. Prefiks into_ jest powszechnym sposobem oznaczania takich metod.

Nie wiem dokładnie, co iter() sposób powraca, ale domyślam się, że to iterator nad &String, to znaczy, że zwraca referencje do String ale nie daje prawa własności do nich. Oznacza to, że użytkownik nie może wywołać metody zużywającej wartość.

Jak można znaleźć, jednym z rozwiązań jest użycie clone. Spowoduje to utworzenie duplikatu obiektu, który użytkownik jest właścicielem i może wywoływać go pod numerem. Jak wspominają inni komentatorzy, możesz również użyć as_bytes, która zajmuje &self, więc będzie działać na pożyczonej wartości. To, którego powinieneś użyć, zależy od celu końcowego, od tego, co robisz ze wskaźnikiem.

W większym obrazie wszystko to ma związek z pojęciem własności. Pewne operacje zależą od posiadania przedmiotu, a inne operacje mogą uciec pożyczając obiekt (być może w sposób mutogenny). Odniesienie (&foo) nie nadaje prawa własności, jest po prostu pożyczką.

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

Przenoszenie własności jest ogólnie pojętą koncepcją - kiedy coś robię, ktoś inny może ją mieć. W Rust, to sposób na zwiększenie wydajności. Mogę uniknąć przydzielenia kopii, dając ci jedną kopię, a następnie wyrzucając moją kopię. Własność jest również najbardziej permisywnym państwem; jeśli posiadam obiekt, mogę zrobić to, co chcę.


Oto kod, który stworzyłem, aby przetestować z:

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

Dziękuję, wszystko było jasne! :) – Peekmo

+1

Po prostu pytanie. Dlaczego interesujące jest używanie (self) zamiast (i self) w funkcji args? – Peekmo

+4

Przenoszenie własności jest ogólnie pojętą koncepcją - kiedy coś robię, ktoś inny może ją mieć. W Rustzie jest to sposób na zwiększenie wydajności (w przeciwieństwie do przydzielania kopii, wydania jednej kopii, a następnie wyrzucenia mojej kopii). Własność jest również najbardziej permisywnym państwem; jeśli posiadam obiekt, mogę zrobić to, co chcę. – Shepmaster

Powiązane problemy