Search code examples
rust

What is the difference between [u8] and Vec<u8> on rust?


What is the difference between [u8] and Vec<u8> on rust?


Solution

  • [u8] represents a contiguous sequence of u8 of arbitrary size. Since its size is unknown at compile time, you can't store it in a variable because a variable needs a fixed size. You cannot pass it to or return it from functions for the same reason, so it's not very useful on its own. The primary use of a slice type like [u8] is to create slice references (like &[u8]), smart pointers (like Box<[u8]>), and in generic types (like AsRef<[u8]>). str wraps (consists of) a [u8] but only allows valid UTF-8.

    &[u8] is a "slice reference" which refers to such a sequence, and also carries information about its length. The reference is represented by a "fat pointer" two machine words wide, consisting of pointer to the data and the length of the data. The size of the slice reference is fixed (two machine words), so it can be stored in variables, passed to functions, and generally used like a normal value. It's the basis for &str.

    Box<[u8]> is like &[u8], except it owns the underlying memory, i.e. the underlying octet sequence is heap-allocated by Box::new() and deallocated on Drop. Just like &[u8], it is two machine words wide. It's the basis for Box<str>.

    Vec<u8> is like Box<[u8]>, except it additionally stores a "capacity" count, making it three machine words wide. Separately stored capacity allows for efficient resizing of the underlying sequence. It's the basis for String.