VecDeque::from(&slice) does not compile

Hi everybody

While doing the latest AdventOfCode I tried to create a VecDeque from a slice the following way:

let slice = &[1, 2, 3];
let _ = VecDeque::from(slice);

This leads to a compile error saying From is not implemented for that type:

help: the following other types implement trait `From<T>`:
          `VecDeque<T, A>` implements `From<Vec<T, A>>`
          `VecDeque<T>` implements `From<[T; N]>`

and yes

let array = [1, 2, 3];
let _ = VecDeque::from(array);

actually works.

However, I can create a Vec from a slice using from.
I wonder WHY it's not implemented for VecDeque?
If it's about copying, then why is extend implemented for a slice?

Any ideas?

Btw, other sources suggest doing

slice.iter().copied().collect()

to create a VecDeque from a slice, which is in my opinion quite elaborate.

It's probably just an oversight in the standard library; it's hard to get complete coverage of this sort of small utility method.


I'd probably write something like this instead:

    let _: VecDeque<_> = Vec::from(slice).into();

or:

    let _: VecDeque<_> = slice.to_owned().into();
7 Likes

Another option here is just

let slice = &[1, 2, 3];
let _ = VecDeque::from_iter(slice);

because from_iter takes anything that can be turned into an iterator.

(Thought that'll give you a VecDeque<&i32>, which you might not want, and thus the slice.iter().copied().collect() is more likely what you're looking for.)

Of course, Vec -> VecDeque is O(1) and doesn't reallocate, so you could also just do VecDeque::from(slice.to_vec()).

5 Likes

Thanks for the tips!

that's cool. I did not know that it does not re-allocate (copy).

You can see this documented in https://doc.rust-lang.org/std/collections/struct.VecDeque.html#impl-From<Vec<T,+A>>-for-VecDeque<T,+A> -- and the other direction is documented in https://doc.rust-lang.org/std/collections/struct.VecDeque.html#impl-From<VecDeque<T,+A>>-for-Vec<T,+A> (it's only sometimes O(1), but it's always non-reallocating as of a couple of releases ago).