Nie rozumiem błędu cannot move out of borrowed content
. Otrzymałem go wiele razy i zawsze go rozwiązywałem, ale nigdy nie rozumiałem dlaczego.
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);
}
powoduje 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
W nowszych wersjach Rusta błąd to
error[E0507]: cannot move out of `*line` which is behind a shared reference
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait
Rozwiązałem to przez sklonowanie line
:
for current_char in line.clone().into_bytes().iter() {
Nie rozumiem błędu nawet po przeczytaniu innych postów typu:
- Nie można pożyczyć pliku z & mut self (komunikat o błędzie: nie można wyjść z wypożyczonej zawartości)
- Zmiana węzła w drzewie w Rust
Jakie jest źródło tego rodzaju błędu?
.bytes()
metodę.).as_bytes()
as_bytes()
bez klonowania. Ale nadal nie rozumiem, dlaczego?String
pobierabytes
metodę zstr
.Odpowiedzi:
Spójrzmy na podpis dla
into_bytes
:To wymaga
self
, a nie odniesienia do self (&self
). Oznacza to, żeself
zostanie zużyty i nie będzie dostępny po połączeniu. W jego miejsce otrzymasz plikVec<u8>
. Przedrostekinto_
jest powszechnym sposobem oznaczania takich metod.Nie wiem dokładnie, co
iter()
zwraca twoja metoda, ale przypuszczam, że jest to iterator&String
, to znaczy zwraca odwołania do a,String
ale nie daje ci do nich własności. Oznacza to, że nie można wywołać metody, która zużywa wartość .Jak odkryłeś, jednym z rozwiązań jest użycie
clone
. To tworzy duplikat obiektu, który zrobić samodzielnie, a może zadzwonićinto_bytes
na. Jak wspominają inni komentatorzy, możesz również użyć tego,as_bytes
który bierze&self
, więc zadziała na pożyczonej wartości. Który z nich należy użyć, zależy od celu końcowego dotyczącego tego, co zrobisz ze wskaźnikiem.W szerszej perspektywie wszystko to ma związek z pojęciem własności . Niektóre operacje zależą od posiadania przedmiotu, a inne operacje mogą uciec z pożyczeniem obiektu (być może na zmianę). Reference (
&foo
) nie przyznaje prawa własności, to tylko pożyczka.Przeniesienie własności jest ogólnie użyteczną koncepcją - kiedy coś skończę, ktoś inny może to mieć. W Rust to sposób na zwiększenie wydajności. Mogę uniknąć przydzielania kopii, dając ci jedną kopię, a następnie wyrzucając moją kopię. Własność jest również najbardziej liberalnym stanem; jeśli posiadam przedmiot, mogę z nim zrobić, jak chcę.
Oto kod, który stworzyłem do przetestowania:
źródło