I am writing a function for a struct which contains a Vec
where I attempt to iterate through the 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
}
}
However I get the following error:
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
My understanding is that since self
is borrowed and that the for loop iteration is attempting to move the elements of v
out into e
.
From the error code, I read that a potential solution is to take ownership but I'm not quite certain how to do that.
I'm not trying to modify the vector or its elements. I just want to use the elements to run some computation.
The line: for e in self.v
is essentially saying for e in (*self).v
; you're attempting to iterate over the vector by move, invoking its IntoIterator
trait. This would destroy the vector completely, moving all the numbers out of it forever, which is not only not what you want, but also not allowed in this context because you're only allowed to read it.
You actually want to iterate over it by reference. There are two ways to do this:
for e in &self.v {
// ...
}
This is essentially saying &((*self).v)
, since the .
auto-dereferences you need to tell the compiler that you actually just want to borrow the vector.
or
for e in self.v.iter() {
// ...
}
This may look funny because iter
takes an &self
. Why? Well, the compiler also auto-references if you call a function on a value that takes a reference. This is essentially (&((*self).v)).iter()
, but that would suck to write so the compiler helps out.
So why doesn't it auto-reference in the for
loop? Well, for x in self.v
is a valid statement, and that may be what you intended to write. It's usually more important for the compiler to tell you that what you want want is impossible than assume you wanted something else. With the auto (de-)referencing above, no such ambiguity exists.
The former solution is preferred, but the latter is necessary if you want to use an iterator adapter.
Speaking of which, your sum
already exists: just write self.v.iter().sum()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With