How to get a slice as an array in Rust? How to get a slice as an array in Rust? arrays arrays

How to get a slice as an array in Rust?


You can easily do this with the TryInto trait (which was stabilized in Rust 1.34):

use std::convert::TryInto;fn pop(barry: &[u8]) -> [u8; 3] {    barry.try_into().expect("slice with incorrect length")}

But even better: there is no need to clone/copy your elements! It is actually possible to get a &[u8; 3] from a &[u8]:

fn pop(barry: &[u8]) -> &[u8; 3] {    barry.try_into().expect("slice with incorrect length")}

As mentioned in the other answers, you probably don't want to panic if the length of barry is not 3, but instead handle this error gracefully.

This works thanks to these impls of the related trait TryFrom (before Rust 1.47, these only existed for arrays up to length 32):

impl<'_, T, const N: usize> TryFrom<&'_ [T]> for [T; N]where    T: Copy, impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N]impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N]


Thanks to @malbarbo we can use this helper function:

use std::convert::AsMut;fn clone_into_array<A, T>(slice: &[T]) -> Awhere    A: Default + AsMut<[T]>,    T: Clone,{    let mut a = A::default();    <A as AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);    a}

to get a much neater syntax:

fn main() {    let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];    let e = Example {        a: clone_into_array(&original[0..4]),        b: clone_into_array(&original[4..10]),    };    println!("{:?}", e);}

as long as T: Default + Clone.

If you know your type implements Copy, you can use this form:

use std::convert::AsMut;fn copy_into_array<A, T>(slice: &[T]) -> Awhere    A: Default + AsMut<[T]>,    T: Copy,{    let mut a = A::default();    <A as AsMut<[T]>>::as_mut(&mut a).copy_from_slice(slice);    a}

Both variants will panic! if the target array and the passed-in slice do not have the same length.


Here's a function that matches the type signature you asked for.

fn pop(barry: &[u8]) -> [u8; 3] {    [barry[0], barry[1], barry[2]]}

But since barry could have fewer than three elements, you may want to return an Option<[u8; 3]> rather than a [u8; 3].

fn pop(barry: &[u8]) -> Option<[u8; 3]> {    if barry.len() < 3 {        None    } else {        Some([barry[0], barry[1], barry[2]])    }}