无法移出借来的内容

我不明白错误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 

我通过克隆line解决了它:

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

即使阅读其他post后,我也不明白这个错误:

  • 无法从&mut自借文件(错误消息:不能移出借用的内容)
  • 在Rust中更改树中的节点

这种错误的起源是什么?

我们来看一下into_bytes的签名:

 fn into_bytes(self) -> Vec<u8> 

这需要self ,而不是对自我( &self )的引用。 这意味着self将被消耗,并在通话后不可用。 取而代之,你会得到一个Vec<u8> 。 前缀into_是表示这种方法的常用方法。

我不知道你的iter()方法返回的是什么,但我的猜测是它是一个迭代器&String ,也就是说,它返回一个String引用,但不会给你所有权。 这意味着你不能调用一个消耗这个值的方法

正如你所发现的,一个解决scheme是使用clone 。 这会创build一个您拥有的重复对象,并可以调用into_bytes 。 正如其他评论者所说,你也可以使用as_bytes这个&self ,所以它会在借来的价值上工作。 你应该使用哪一个取决于你对指针做什么的最终目标。

从更大的angular度来看,这一切都与所有权的概念有关。 某些操作取决于拥有该项目,其他操作可以借用该对象(可能是可变的)而逃脱。 参考( &foo )不授予所有权,这只是一个借用。

为什么在函数的参数中使用self而不是&self

所有权转让是一个有用的概念 – 当我完成某件事情时,其他人可能拥有它。 在Rust,这是一种更高效的方法。 我可以避免分配一个副本,给你一个副本,然后扔掉我的副本。 所有权也是最宽松的状态; 如果我拥有一个对象,我可以按照自己的意愿去做。


以下是我创build的用于testing的代码:

 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() {}