首页 文章

无法摆脱借来的内容

提问于
浏览
85

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

我通过克隆_273039解决了这个问题:

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

即使在阅读其他帖子之后我也不明白这个错误:

这种错误的起源是什么?

1 回答

  • 80

    我们来看看into_bytes的签名:

    fn into_bytes(self) -> Vec<u8>
    

    这需要 self ,而不是对self( &self )的引用 . 这意味着 self 将被消耗,并且在通话后将无法使用 . 取而代之的是 Vec<u8> . 前缀 into_ 是表示这样的方法的常用方法 .

    我不知道你的 iter() 方法究竟返回了什么,但我的猜测是它是一个超过 &String 的迭代器,也就是说,它返回对 String 的引用,但并没有给你它们的所有权 . 这意味着您无法调用消耗该值的方法 .

    如您所见,一种解决方案是使用 clone . 这会创建一个您拥有的重复对象,并且可以调用 into_bytes . 正如其他评论者提到的那样,你也可以使用as_bytes,它需要 &self ,因此它可以使用借来的值 . 您应该使用哪一个取决于您使用指针执行操作的最终目标 .

    从更大的角度来看,这一切都与所有权概念有关 . 某些操作依赖于拥有该项目,而其他操作可以通过借用该对象而逃脱(可能是可变的) . 引用( &foo )不授予所有权,它只是借用 .

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

    转移所有权通常是一个有用的概念 - 当我完成某些事情时,其他人可能拥有它 . 在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() {}
    

相关问题