Moving a field of an object in vector index

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.

Leave a Reply