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

时间:2016-08-05 09:23:20

标签: rust

我正在为包含$a=$this->A->find('all', ['conditions' => ['b'=>5, 'c >'=>1000]])->first(); 的结构编写一个函数,我尝试遍历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
    }
}

我的理解是,借用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 并且for循环迭代试图将self的元素移到v

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

我没有尝试修改矢量或其元素。我只是想用这些元素来运行一些计算。

1 个答案:

答案 0 :(得分:16)

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

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

for e in &self.v {
    // ...
}

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

for e in self.v.iter() {
    // ...
}

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

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

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

说到这一点,您的sum已经存在:只需撰写self.v.iter().sum()