HiveBrain v1.2.0
Get Started
← Back to all entries
snippetrustCritical

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

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
arraygoodconvertwayvecthere

Problem

Is there a good way to convert a Vec 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, 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?

Solution

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(v: Vec) -> [T; N] {
    v.try_into()
        .unwrap_or_else(|v: Vec| 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(v: Vec) -> [T; 4] {
v.try_into()
.unwrap_or_else(|v: Vec| panic!("Expected a Vec of length {} but it was {}", 4, v.len()))
}


As of Rust 1.43:

use std::convert::TryInto;

fn demo(v: Vec) -> [T; 4] {
    let boxed_slice = v.into_boxed_slice();
    let boxed_array: Box = 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?

Code Snippets

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()))
}
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
}

Context

Stack Overflow Q#29570607, score: 141

Revisions (0)

No revisions yet.