I have a Vec
of nontrivial types with a size I am certain of. I need to convert this into fixed size array. Ideally I would like to do this
Vec
Question written as code:
struct Point {
x: i32,
y: i32,
}
fn main() {
let points = vec![
Point { x: 1, y: 2 },
Point { x: 3, y: 4 },
Point { x: 5, y: 6 },
];
// I would like this to be an array of points
let array: [Point; 3] = ???;
}
This seems like a trivial issue, however I have not been able to find satisfactory solution in Vec
docs, slicing sections of Rust Books or by Googling. Only thing that I found is to first initialize the array with zero data and later copy all elements over from Vec
, however this does not satisfy my requirements.
Doing this correctly is exceedingly difficult. The problem lies in properly handling a panic when there's a partially uninitialized array. If the type inside the array implements Drop
, then it would access uninitialized memory, causing undefined behavior.
The easiest, safest way is to use arrayvec:
extern crate arrayvec;
use arrayvec::ArrayVec;
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let points = vec![
Point { x: 1, y: 2 },
Point { x: 3, y: 4 },
Point { x: 5, y: 6 },
];
let array: ArrayVec<_> = points.into_iter().collect();
let array: [Point; 3] = array.into_inner().unwrap();
println!("{:?}", array);
}
Beware this only works for specific sizes of arrays because Rust does not yet have generic integers. into_inner
also has a performance warning you should pay attention to.
See also:
What is the proper way to initialize a fixed length array? (especially this answer)
Convert vectors to arrays and back, which inadvertently wrote code that worked without copies, but does not explicitly claim it was on purpose
How to get a slice as an array in Rust?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With