Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a good way to convert a Vec<T> to an array?

Tags:

rust

Is there a good way to convert a Vec<T> with size S to an array of type [T; S]? Specifically, I'm using a function that returns a 128-bit hash as a Vec<u8>, which will always have length 16, and I would like to deal with the hash as a [u8, 16].

Is there something built-in akin to the as_slice method which gives me what I want, or should I write my own function which allocates a fixed-size array, iterates through the vector copying each element, and returns the array?

like image 348
jgray Avatar asked Apr 10 '15 20:04

jgray


1 Answers

Arrays must be completely initialized, so you quickly run into concerns about what to do when you convert a vector with too many or too few elements into an array. These examples simply panic.

As of Rust 1.51 you can parameterize over an array's length.

use std::convert::TryInto;  fn demo<T, const N: usize>(v: Vec<T>) -> [T; N] {     v.try_into()         .unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len())) } 

As of Rust 1.48, each size needs to be a specialized implementation:

use std::convert::TryInto;  fn demo<T>(v: Vec<T>) -> [T; 4] {     v.try_into()         .unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", 4, v.len())) } 

As of Rust 1.43:

use std::convert::TryInto;  fn demo<T>(v: Vec<T>) -> [T; 4] {     let boxed_slice = v.into_boxed_slice();     let boxed_array: Box<[T; 4]> = match boxed_slice.try_into() {         Ok(ba) => ba,         Err(o) => panic!("Expected a Vec of length {} but it was {}", 4, o.len()),     };     *boxed_array } 

See also:

  • How to get a slice as an array in Rust?
  • How do I get an owned value out of a `Box`?
  • Is it possible to control the size of an array using the type parameter of a generic?
like image 192
Shepmaster Avatar answered Oct 02 '22 14:10

Shepmaster