0

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); } 
1
  • 1
    What should be the desired output? As written, z would be guaranteed to be empty, for example. Commented Mar 19, 2022 at 5:37

1 Answer 1

2

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)

Sign up to request clarification or add additional context in comments.

5 Comments

Is there a single function that will do x.splice(...).collect::<Vec<_>>();? It's rather verbose.
@Test No, but you can write your own.
How does one do so? Do you mean contribute to the standard library? If not, how does one add a method to an existing data structure via an external library?
@Test You can either write an extension trait and implement it on Vec or you can just write a free function and invoke it without using method syntax.
Ok, I've added a question about how to define an extension trait via an external module.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.