how can I convert an array to a vec without cloning the values
Make a Vec of references:
array.iter_mut().collect::<Vec<_>>();no cloning involved, and you have a Vec.
In practice, however, it's gonna be lifetime-bound (Vec<&mut T> or Vec<&T> if using .iter()).
Hence the following more useful answer, but it may involve cloning or other stuff.
In the following snippets, consider that array is an expression of type [T; N] (an array), or a [T] (a slice), but then behind some form of indirection (slices need pointer indirection): &[T], &mut [T] or Box<[T]> (or &move [T]).
To avoid extra lifetime/borrowing restrictions, you'll need to have owned values in the resulting Vec. For that, you:
-
either go from
T -> T, by moving, e.g.,::core::array::IntoIter::new(array) // does not work for slices unless boxed, see below .collect::<Vec<_>>()
- If you are sure
arrayis an owned array, and if your project is using the 2021 edition, then you can usearray.into_iter()directly rather than::{core,std}::array::IntoIter::new().
- If you are sure
-
or
&T -> T, by cloning, e.g.,array.iter() // works for slices .cloned() // same as `.map(Clone::clone)` or `.map(|it| it.clone())` .collect::<Vec<_>>()
-
or
&mut T -> T, by taking / replacing, e.g.,array.iter_mut() // works for slices .map(::core::mem::take) // or .map(|it| ::core::mem::replace(it, somme_dummy)) .collect::<Vec<_>>()
You can support moving with slices if it was behind a Box:
let _: Box<[T]> = boxed_slice;
Vec::from(boxed_slice)-
For the sake of completeness,
Boxis technically not the only way to allow this. With&move/&ownreferences, it is theoretically possible to consider:let _: &move [T] = owned_slice; Vec::from(owned_slice)
But
&move"references" are not yet part of Rust (and from the looks of it, may never be 😢). See https://docs.rs/stackbox for a cumbersome third-party implementation of those semantics, and thus more info about it.