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

// Before Rust 2021, you need to import the trait:
// use std::convert::TryInto;

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

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 should have length 3")
}

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]
Answer from Lukas Kalbertodt on Stack Overflow
🌐
Rust
doc.rust-lang.org › std › primitive.slice.html
slice - Rust
The end pointer requires extra caution, as it does not point to a valid element in the slice. This function is useful for interacting with foreign interfaces which use two pointers to refer to a range of elements in memory, as is common in C++. ... Gets a reference to the underlying array.
Top answer
1 of 9
202

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

// Before Rust 2021, you need to import the trait:
// use std::convert::TryInto;

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

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 should have length 3")
}

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]
2 of 9
24

Thanks to @malbarbo we can use this helper function:

use std::convert::AsMut;

fn clone_into_array<A, T>(slice: &[T]) -> A
where
    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]) -> A
where
    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.

🌐
Programiz
programiz.com › rust › slice
Rust Slice (With Examples)
A Rust slice is a data type used to access portions of data stored in collections like arrays, vectors and strings.
🌐
Codecademy
codecademy.com › docs › rust › slices
Rust | Slices | Codecademy
May 15, 2024 - Slices in Rust are references to consecutive elements in memory, allowing you to reference parts of a collection without copying the entire data, providing a view into arrays, vectors, or other sequences for focused data manipulation.
🌐
MIT
web.mit.edu › rust-lang_v1.25 › arch › amd64_ubuntu1404 › share › doc › rust › html › rust-by-example › primitives › array.html
Arrays and Slices - Rust By Example
use std::mem; // This function borrows a slice fn analyze_slice(slice: &[i32]) { println!("first element of the slice: {}", slice[0]); println!("the slice has {} elements", slice.len()); } fn main() { // Fixed-size array (type signature is superfluous) let xs: [i32; 5] = [1, 2, 3, 4, 5]; // All elements can be initialized to the same value let ys: [i32; 500] = [0; 500]; // Indexing starts at 0 println!("first element of the array: {}", xs[0]); println!("second element of the array: {}", xs[1]); // `len` returns the size of the array println!("array size: {}", xs.len()); // Arrays are stack all
🌐
Rust
docs.rs › slice-of-array
slice_of_array - Rust
Permits viewing a slice of arrays as a flat slice.
🌐
The Rust Programming Language
doc.rust-lang.org › book › ch04-03-slices.html
The Slice Type - The Rust Programming Language
String slices, as you might imagine, are specific to strings. But there’s a more general slice type too. Consider this array:
Find elsewhere
🌐
Rust By Example
doc.rust-lang.org › rust-by-example › flow_control › match › destructuring › destructure_slice.html
arrays/slices - Rust By Example
let array = [1, -2, 6]; match array { // Binds the second and the third elements to the respective variables [0, second, third] => println!("array[0] = 0, array[1] = {}, array[2] = {}", second, third), // Single values can be ignored with _ [1, _, third] => println!( "array[0] = 1, array[2] = {} and array[1] was ignored", third ), // You can also bind some and ignore the rest [-1, second, ..] => println!( "array[0] = -1, array[1] = {} and all the other ones were ignored", second ), // The code below would not compile // [-1, second] => ... // Or store them in another array/slice (the type depe
🌐
Dev-notes
dev-notes.eu › 2019 › 07 › arrays-slices-in-rust
Arrays and Slices in Rust | Dev Notes
// Arrays in rust are fixed length. // Specify type and length in square brackets to initialize. let arr: [i32; 5] = [1, 2, 3, 4, 5]; The correct data type and array length are now fixed and expected. ... Arrays are not iterable. To iterate over each element, convert an array to iterator by calling .iter(), a slice method:
🌐
TutorialsPoint
tutorialspoint.com › rust › rust_slices.htm
Rust - Slices
The main() function declares an array with 5 elements. It invokes the use_slice() function and passes to it a slice of three elements (points to the data array). The slices are passed by reference.
🌐
DEV Community
dev.to › francescoxx › slices-in-rust-g6
Slices in Rust - DEV Community
March 5, 2024 - Rust has a built-in type called Slice that is used to reference a contiguous sequence of elements in a collection. Slices are a very important concept in Rust, and they are used extensively in the standard library.
🌐
Reddit
reddit.com › r/learnrust › easy way to slice 2d arrays in rust for beginners, get columns and square slices from your arrays
r/learnrust on Reddit: Easy way to slice 2d arrays in rust for beginners, get columns and square slices from your arrays
June 5, 2020 -

I was playing around with 2d arrays in rust and wondered if there was a way to get python pandas like behaviour of slicing DataFrames in rust. I experimented with iterators a bit and came up with this. It's probably not the most elegant solution but might be nice in a pinch for beginners, also works on vectors:

fn main() {
    let arr = [
        [1, 2, 3, 4, 5, 6, 7, 8, 9],
        [10, 11, 12, 13, 14, 15, 16, 17, 18],
        [19, 20, 21, 22, 23, 24, 25, 26, 27],
        [28, 29, 30, 31, 32, 33, 34, 35, 36],
        [37, 38, 39, 40, 41, 42, 43, 44, 45],
        [46, 47, 48, 49, 50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59, 60, 61, 62, 63],
        [64, 65, 66, 67, 68, 69, 70, 71, 72],
        [73, 74, 75, 76, 77, 78, 79, 80, 81],
    ];

    //get the 4th row
    let row = arr[3];
    println!("row: {:?}", row);

    //get the 6th column
    let col = arr
        .iter()
        .map(|s| s.iter().nth(5).unwrap())
        .collect::<Vec<_>>();
    println!("col: {:?}", col);

    //get a 4x4 slice starting at 2,2
    let (x, y, z) = (2, 2, 4);
    let slice = arr
        .iter()
        .skip(x)
        .take(z)
        .map(|s| s.iter().skip(y).take(z).collect::<Vec<_>>())
        .collect::<Vec<_>>();
    println!("slice: {:?}", slice);

    //get a 5x5 slice starting at 1,1 and flatten into 1d vector
    let (x, y, z) = (1, 1, 5);
    let slice = arr
        .iter()
        .skip(x)
        .take(z)
        .map(|s| s.iter().skip(y).take(z).collect::<Vec<_>>())
        .flatten()
        .collect::<Vec<_>>();
    println!("flat slice: {:?}", slice);
}

Here is the output:

row: [28, 29, 30, 31, 32, 33, 34, 35, 36]
col: [6, 15, 24, 33, 42, 51, 60, 69, 78]
slice: [[21, 22, 23, 24], [30, 31, 32, 33], [39, 40, 41, 42], [48, 49, 50, 51]]
flat slice: [11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51]
🌐
Rust
docs.rs › slice_as_array
slice_as_array - Rust
slice_as_array!(xs, [u32; 4]) returns Some(&[u32; 4]) if xs was a slice of length 4, or None otherwise.
🌐
NAPALM
saidvandeklundert.net › learn › 2021-08-14-rust-slice
Rust slice
But somewhere in the rust-lang Github repo, the slice is defined as follows: Slices are a view into a block of memory represented as a pointer and a length. I found this more helpful.
🌐
Rust
doc.rust-lang.org › std › slice › index.html
std::slice - Rust
Array · Windows · Experimental · A windowed iterator over a slice in overlapping chunks (N elements at a time), starting at the beginning of the slice · GetDisjoint · MutError · The error type returned by get_disjoint_mut. Slice · Index · A helper trait used for indexing operations.
🌐
crates.io
crates.io › crates › slice-of-array
slice-of-array - crates.io: Rust Package Registry
Extension traits for casting between slices and slices of arrays. (&[T] &[[T; n]])
🌐
Brandeis University
cs.brandeis.edu › ~cs146a › rust › doc-02-21-2015 › book › arrays-vectors-and-slices.html
Arrays, Vectors, and Slices
A slice is a reference to (or "view" into) an array. They are useful for allowing safe, efficient access to a portion of an array without copying. For example, you might want to reference just one line of a file read into memory. By nature, a slice is not created directly, but from an existing ...