Search code examples
rust

Why are slices dynamically sized?


In the tutorial it explains &str is a slice reference to str. str is the slice. And we can create a slice like this:

let string: &str = "a string";
let arr: [i32; 4] = [1, 2, 3, 4];
let arr_slice: &[i32] = &arr[..2];

Here, I think, the size of slice is quite clear. arr_slice has a reference to two i32 elements. If I understand it, the equivalent in C would look like:

typedef struct {
    void* ptr;
    int length;
} slice;

The length can be known through the slice syntax [...]. Thus, size of slice can also be inferred by sizeof(type of ptr) * length which behaves like array. So that in the example above, it's very easy to know the size of slice itself at compile time.

Why does Rust make slice a DST?


Solution

  • In short, because that's what they are designed to be, a sequence of items of dynamic length. There is an inherent need to handle variable-length sequences for many programs.

    The code you show doesn't need to use a dynamic slice, for it, in theory slicing could work like this:

    let arr_slice: &[i32; 2] = &arr[..2];
    

    But that now means the index has to be known at compile time, you can't use user input to get a subset. The following code:

    let length = rand::Rng::gen_range(&mut rand::thread_rng(), 0..=arr.len());
    let arr_slice = &arr[..length];
    

    is no longer possible because you can't know the runtime value length at compile time.