How to Get a Slice as an Array in Rust: From Beginner to Guru

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Slice as an Array in Rust: Why It's Hard and How to Do It Right

\n\n

Anyone who has written Rust for more than a couple of days has encountered this frustrating situation: you have a &[u8] (slice), but the function needs a [u8; 4] (array). In C, you'd just take a pointer. In Python, you'd slice it. In Rust... the dance begins. But don't be scared — behind this complexity lies brilliant safety.

\n\n

In this article, we'll cover how to get a slice as an array in Rust using every possible method: from "quick and dirty" to "correct and reliable." You'll learn why Rust doesn't just let you turn a slice into an array, and how to work around this "problem" with maximum performance.

\n\n

Why Doesn't Rust Simply Allow Copying a Slice into an Array?

\n\n

Imagine you order a pizza, and they bring you a slice. You say, "This is part of a pizza, make it whole." That's how it is with a slice — it's a reference to a piece of data, while an array is an owning type of fixed length. The size of an array is known at compile time, but the size of a slice is only known at runtime.

\n\n

Therefore, you can't just write let arr: [u8; 4] = slice. The compiler will say, "Sorry, I don't know if your slice will fit into an array of 4 elements." Rust prioritizes safety above all else — if the slice is shorter, you'll get garbage or a panic.

\n\n

Method 1: try_into() — Modern and Safe Method

\n\n

Starting from Rust 1.47, an elegant method appeared via the TryInto trait. This is the recommended method for converting a slice to an array. It returns a Result, so you always know if the conversion was successful.

\n\n
use std::convert::TryInto;\n\nfn main() {\n    let slice: &[u8] = &[10, 20, 30, 40, 50];\n    \n    // Attempt to get an array of 3 elements\n    let result: Result<[u8; 3], _> = slice[..3].try_into();\n    \n    match result {\n        Ok(arr) => println!("Array: {:?}", arr),\n        Err(_) => println!("Not enough elements!"),\n    }\n    \n    // Or just use unwrap if you're sure\n    let arr: [u8; 4] = slice[..4].try_into().unwrap();\n    println!("Array of 4: {:?}", arr);\n}
\n\n

How does it work? The try_into() method checks the slice length at runtime. If the length matches, it converts; if not, it returns an error. This is the ideal solution for 99% of cases.

\n\n

Method 2: copy_from_slice() — For Those Who Like Control

\n\n

If you already have an array (e.g., initialized with zeros), you can copy data from the slice. This method requires the slice to be no shorter than the array — otherwise, it will panic.

\n\n
fn main() {\n    let slice: &[u32] = &[100, 200, 300];\n    let mut arr: [u32; 3] = [0; 3]; // create an empty array\n    \n    arr.copy_from_slice(slice);\n    println!("Copied: {:?}", arr);\n    \n    // If the slice is longer — take a subset\n    let long_slice = &[1, 2, 3, 4, 5];\n    let mut small_arr = [0u8; 2];\n    small_arr.copy_from_slice(&long_slice[..2]);\n    println!("Part of slice: {:?}", small_arr);\n}
\n\n

Important: copy_from_slice only works for types that implement Copy (e.g., numbers). For strings, use clone_from_slice.

\n\n

Method 3: Manual Iteration — For the Adventurous

\n\n

Sometimes you need to do something non-standard. For example, convert a slice with reordering or filtering. In that case, you can iterate manually:

\n\n
fn slice_to_array<T: Copy, const N: usize>(slice: &[T]) -> Option<[T; N]> {\n    if slice.len() != N {\n        return None;\n    }\n    \n    let mut arr = [unsafe { std::mem::zeroed() }; N];\n    for (i, &val) in slice.iter().enumerate() {\n        arr[i] = val;\n    }\n    Some(arr)\n}\n\nfn main() {\n                

Blogs

Book Recommendations