Search code examples
arraysrustslice

How does Rust determine the length of a slice when unsizing from an array?


I know that a slice is like a fatptr: (data_ptr, len). When I slice an array into a slice:

let arr = [0; 10];
let slice_arr = &arr[..];

An array doesn't have a length field like Vec<T>.

I know that slice_arr.len() can get the length of slice because slice_arr has a length field. How does Rust know the length field when an array is converted into a slice?


Solution

  • An array does have a length "parameter" of sorts. It's not a field, it's part of the type:

    let x: [u8; 2] = [1, 2];
    let y: [u8; 3] = x; // Error here
    

    The type of x is [u8; 2]. The number of elements is always 2, and the type of the elements is always u8.

    Because [u8; 2] and [u8; 3] are distinct types, one is always exactly 2 u8s long, and the other is always exactly 3 u8s long, the assignment from x into y fails.

    When performing certain operations with arrays, the compiler has special built-in semantics for the arrays. These built-in semantics can make use of the length "parameter" (The N in [T; N]).

    You can manipulate and access this value at the type level using const generics, for example, this function accepts arrays of any length:

    fn foo<const N: usize>(array: [u8; N]) {
        // ...
    }