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
array
is 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,
Box
is technically not the only way to allow this. With&move
/&own
references, 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.