Arrays offer a fixed-size collection of values on the stack. Slices allow you to talk about any collection of values, regardless of where they’re stored or how many of them there are. What if we want to have a dynamic size? Just like we need a special struct String to hold heap-allocated strings, we need a special struct, Vec, to hold heap-allocated collections of arbitrary data.

I already bored you to death with the UTF-8 talk above. I’ll say this one much quicker, a String is a thin wrapper around a Vec of u8 values, with the guarantee that the data is valid UTF-8. Tada!

But how exactly do we say “a Vec of u8 values?” How do we distinguish a Vec of u32s from a Vec of bools? We need to introduce something called type parameters. A struct in Rust is allowed to take extra information about which types to use. And the way we say that is with the less than and greater than signs, also known as angle brackets. Or said with code, a vector of bytes is a Vec<u8>. A vector of bools is a Vec<bool>.

NOTE: We can use type parameters for many things. We’ll see how to define structs, functions, and other things that use them later in this course. For now, we’ll stick to using preexisting types in Rust like Vec that use them.

Alright, let’s finally see some Vec code!

Get hands-on with 1000+ tech skills courses.