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?
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.