My question aims at understanding a deeper variant of the "cannot move out of index" error, specifically when I want to move a field of a struct that resides in a vector. Below is a classical example of a vector of objects and an attempt to move a field out of it.
struct Foo {
str_val: String,
int_val: i32,
}
fn main() {
let mut foos = Vec::new();
foos.push(Foo {
str_val: "ten".to_string(),
int_val: 10,
});
foos.push(Foo {
str_val: "twenty".to_string(),
int_val: 20,
});
// Here understandable error.
let moved = foos[0];
// Why also an error? "cannot move out of index of `Vec<Foo>`"
let moved_field = foos[0].str_val;
}
My question:
- while I do understand why one cannot move the whole object occupying the element of the index (i.e. because the contiguous index is its owner), but
- what I don’t understand is why one cannot move a field of such an object.
- The logical counter-reasoning I have is that it is allowed to move a field out of a standalone object, and rust appears advanced enough to track the ownership of fields separately:
let mut standalone = Foo {
str_val: "thirty".to_string(),
int_val: 30,
};
let moved_thirty = standalone.str_val;
// Rust seems to be completely ok with tracking fields separately.
let int_moved = standalone.i32;
// "use of moved value: `standalone.str_val`"
let error = standalone.str_val;
>Solution :
When one make a partial move out of a variable the parent variable cannot be used as a whole anymore, since you have stored the object in a vector this is forbidden, for instance the vector may need to move to reallocate more space.