Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Built in *safe* way to move out of Vec<T>?

Tags:

rust

I've been looking over the documentation, and so far I haven't seen a built in function to safely move an item out of a Vec.

Vec::get exists, but that just borrows. Vec::remove exists, and while that does move out of the vector, it also panics if the index is out of range. So, I have two questions:

  1. What is the intended/good way to move an item from a vector?
  2. remove(&mut self, index: usize) -> T panics if out of range. What might be the reason for panicking? Why isn't it implemented like remove(&mut self, index: usize) -> Option<T>?
like image 408
FizzBazer Avatar asked May 27 '16 17:05

FizzBazer


3 Answers

If you say safe in a Rust context, we think of memory safety. .remove(i) is certainly safe in regular Rust terms, just to clarify. Calling panic!() is safe.

The error behavior of .remove(i) and .swap_remove(i) is the same as for indexing a vector with v[i] syntax: If i is out of bounds, it's a programmer bug and the library functions panic. This is also called the contract violation clause in the error handling guidelines.

So the thought behind the library is that you only use v[i] or v.remove(i) if you know that i is in bounds, and you can indeed check that it is using i < v.len() or v.get(i) if you want.

There's another function that allows you to move an element out of a vector without possibility to panic, and that is v.pop() which removes the last item in the vector, returning Option<T> for a Vec<T>.

like image 86
bluss Avatar answered Oct 05 '22 10:10

bluss


There's also vec::drain which will give you an iterator over a range of values that were removed. Now that I look at it though, this method would also panic on out-of-bounds access...

like image 31
GhotiPhud Avatar answered Oct 05 '22 10:10

GhotiPhud


You can use Vec::into_iter() to get an iterator that yields moved objects, and then use iterator APIs to select the item you want.

To move the first item out of a Vec (and throw away all others):

my_vec.into_iter().next()
    .expect("Expecting at least 1 item in vec")
like image 26
sffc Avatar answered Oct 05 '22 10:10

sffc