Reputation: 1648
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
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 T
s 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 aVec
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