Я не понимаю ошибки cannot move out of borrowed content
. Я получал ее много раз и всегда решал ее, но никогда не понимал почему.
Например:
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);
}
выдает ошибку:
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
В более новых версиях Rust ошибка
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
Решил клонированием line
:
for current_char in line.clone().into_bytes().iter() {
Я не понимаю ошибки даже после прочтения других сообщений, например:
- Не удается заимствовать файл из & mut self (сообщение об ошибке: невозможно выйти из заимствованного содержимого)
- Изменение узла в дереве в Rust
В чем причина такого рода ошибок?
.bytes()
.as_bytes()
as_bytes()
без клонирования. Но я все еще не понимаю, почему?String
получаетbytes
метод отstr
.Ответы:
Посмотрим на подпись
into_bytes
:Это берет
self
, а не ссылку на self (&self
). Это означает, чтоself
они будут израсходованы и не будут доступны после вызова. Вместо него вы получите файлVec<u8>
. Префиксinto_
- это обычный способ обозначения подобных методов.Я не знаю точно, что
iter()
возвращает ваш метод, но предполагаю, что это итератор&String
, то есть он возвращает ссылки на a,String
но не дает вам права собственности на них. Это означает, что вы не можете вызвать метод, который потребляет значение .Как вы выяснили, одно из решений - использовать
clone
. Это создает дубликат объекта , который вы сделать самостоятельно, и можете позвонитьinto_bytes
на. Как отмечают другие комментаторы, вы также можете использоватьas_bytes
какие дубли&self
, так что он будет работать с заимствованным значением. Какой из них вы должны использовать, зависит от вашей конечной цели для того, что вы делаете с указателем.В более широком плане все это связано с понятием собственности . Некоторые операции зависят от владения предметом, а другие операции могут уйти с заимствованием объекта (возможно, изменчиво). Ссылка (
&foo
) не дает права собственности, это просто заимствование.Передача права собственности - это вообще полезная концепция: когда я что-то закончил, это может получить кто-то другой. В Rust это способ быть более эффективным. Я могу не выделять копию, не давать вам одну копию, а затем выбросить свою копию. Право собственности также является наиболее разрешающим состоянием; если у меня есть объект, я могу делать с ним все, что хочу.
Вот код, который я создал для тестирования:
источник