2015-01-26 56 views
65

我不明白错误cannot move out of borrowed content。我已经收到了很多次,我一直都在解决它,但我从来不明白为什么。无法移出借用内容

例如:即使读一后

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

我不明白的错误:

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帖子如:

什么是这种错误的由来?

+1

你看着[类似这样的问题(http://stackoverflow.com/q/28034646/1256624)? (顺便说一下,字符串提供'.bytes()'方法)。 – huon 2015-01-26 21:13:05

+0

是的,我看着它,但不明白:(而且我的字符串是一个std :: string :: String,根据文档,没有.bytes()方法 – Peekmo 2015-01-26 21:15:48

+3

它被称为'.as_bytes()' – bluss 2015-01-26 21:37:58

回答

61

让我们看看签名into_bytes

fn into_bytes(self) -> Vec<u8> 

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

我不知道我的猜测正是你iter()方法返回,但它是在&String的迭代器,也就是说,它返回引用到String,但不给你他们的所有权。这意味着您无法调用消耗值的方法。

正如您发现的,一种解决方案是使用clone。这会创建一个重复的对象,您可以使用做的,并且可以调用into_bytes。正如其他评论者所说,你也可以使用as_bytes,这需要&self,所以它会用借来的价值。你应该使用哪一个取决于你对指针做什么的最终目标。

从更大的图片中,这一切都与所有权的概念有关。某些操作取决于拥有该项目,其他操作可能会借用该对象(可能是可变的)。参考(&foo)不授予所有权,它只是一个借用。

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

转让所有权是一种有用的概念 - 当我完成某件事情时,其他人可能拥有它。在Rust中,这是一种提高效率的方法。我可以避免分配一个副本,给你一个副本,然后扔掉我的副本。所有权也是最宽容的状态;如果我拥有一个物体,我可以随心所欲地做它。


下面是我创建了测试代码:

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

谢谢,这一切都很清楚! :) – Peekmo 2015-01-26 22:11:28

+1

只是一个问题。为什么在函数参数中使用(self)而不是(&self)有趣? – Peekmo 2015-01-26 22:58:45

+4

转让所有权是一个有用的概念 - 当我完成某件事时,其他人可能拥有它。在Rust中,这是一种提高效率的方法(与分配副本相反,给你一个副本,然后丢弃我的副本)。所有权也是最宽容的状态;如果我拥有一个物体,我可以随心所欲地做它。 – Shepmaster 2015-01-26 23:42:54