迭代结构中的Vec - 无法摆脱借来的内容

ill*_*zur 11 rust

我正在为一个结构编写一个函数,该结构包含Vec我尝试迭代的地方Vec:

struct Object {
    pub v: Vec<f32>,
}

impl Object {
    pub fn sum(&self) -> f32 {
        let mut sum = 0.0;
        for e in self.v {
            sum += e;
        }
        sum
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

error[E0507]: cannot move out of borrowed content
 --> src/lib.rs:8:18
  |
8 |         for e in self.v {
  |                  ^^^^ cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)

我的理解是,因为self借用了并且for循环迭代试图将vout 的元素移动到e.

从错误代码中,我读到一个潜在的解决方案是取得所有权,但我不太确定如何做到这一点.

我不是要修改向量或其元素.我只是想使用这些元素来运行一些计算.

Lin*_*ope 18

这条线:for e in self.v基本上是说for e in (*self).v; 你试图通过移动迭代矢量,调用它的IntoIterator特性.这将完全破坏向量,永久地移出所有数字,这不仅不是你想要的,而且在这种情况下也不允许,因为你只能阅读它.

你实际上想通过引用迭代它.有两种方法可以做到这一点:

for e in &self.v {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这基本上是说&((*self).v),因为.自动解引用你需要告诉编译器你实际上只想借用向量.

要么

for e in self.v.iter() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这可能看起来很有趣,因为iter需要&self.为什么?好吧,如果你在一个接受引用的值上调用一个函数,编译器也会自动引用.这基本上就是这样(&((*self).v)).iter(),但编写起来会很糟糕,所以编译器会帮忙.

那么为什么它不在for循环中自动引用呢?嗯,这for x in self.v是一个有效的陈述,这可能是你打算写的.对于编译器而言,通常更重要的是告诉您想要的东西是不可能的,而不是假设您想要其他东西.通过上面的自动(取消)引用,不存在这种歧义.

前一种解决方案是首选,但如果您想使用迭代器适配器,后者是必需的.

说到这,你sum已经存在:只需写self.v.iter().sum().