Test
Test

Reputation: 1720

Immutable Borrows for the Same Data Structure

I'm trying to call the "splice" method twice on the same vec.

I'm aware why it fails: the rules make sense. What I don't know is how to accomplish what I want. Is there a way to prove to the compiler that nothing will go wrong?

fn main() {
    let mut x = vec![1, 2, 3, 4, 5];
    let y = x.splice(2.., []);
    let z = x.splice(2.., []);
    println!("{:?}", x);
    println!("{:?}", y);
    println!("{:?}", z);
}

Upvotes: 0

Views: 65

Answers (1)

cdhowie
cdhowie

Reputation: 168958

You can't prove that nothing will go wrong with your code, because with something will go wrong the way you have this written!

The value returned by splice() is a bit special. It's a Splice struct. The vector still owns the elements you asked it to remove immediately after splice() returns.

Splice is an Iterator. When you iterate it, it moves the values out of the original vector to produce them.

When the Splice value is dropped, the replacement items are enumerated and moved into the vector. So while the Splice exists, the splice operation is in a partially-completed state.

Now it should be clear why you can't call .splice() again while a Splice from the same vector still exists -- the vector is still mutably borrowed, because the splice isn't complete.

To fix your problem, you need to drop any extant Splice value before attempting to do anything else with the vector. It looks like you want to move the removed elements into a new vector, so you can just .collect() the Splices. Doing this in a single statement drops the Splice at the end of the statement, because it is a temporary.

    let y = x.splice(2.., []).collect::<Vec<_>>();
    let z = x.splice(2.., []).collect::<Vec<_>>();

(Playground)

Upvotes: 2

Related Questions