leshow
leshow

Reputation: 1648

What is the difference between Vec<struct> and &[struct]?

I often find myself getting an error like this:

mismatched types: expected `collections::vec::Vec<u8>`, found `&[u8]` (expected struct collections::vec::Vec, found &-ptr)

As far as I know, one is mutable and one isn't but I've no idea how to go between the types, i.e. take a &[u8] and make it a Vec<u8> or vice versa.

What's the different between them? Is it the same as String and &str?

Upvotes: 13

Views: 6958

Answers (1)

Shepmaster
Shepmaster

Reputation: 430673

Is it the same as String and &str?

Yes. A Vec<T> is the owned variant of a &[T]. &[T] is a reference to a set of Ts laid out sequentially in memory (a.k.a. a slice). It represents a pointer to the beginning of the items and the number of items. A reference refers to something that you don't own, so the set of actions you can do with it are limited. There is a mutable variant (&mut [T]), which allows you to mutate the items in the slice. You can't change how many are in the slice though. Said another way, you can't mutate the slice itself.

take a &[u8] and make it a Vec

For this specific case:

let s: &[u8]; // Set this somewhere
Vec::from(s);

However, this has to allocate memory not on the stack, then copy each value into that memory. It's more expensive than the other way, but might be the correct thing for a given situation.

or vice versa

let v = vec![1u8, 2, 3];
let s = v.as_slice();

This is basically "free" as v still owns the data, we are just handing out a reference to it. That's why many APIs try to take slices when it makes sense.

Upvotes: 11

Related Questions