Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 377
leshow Avatar asked Dec 18 '14 20:12

leshow


People also ask

How do you define a struct vector?

To create a vector of structs, define the struct, with a generalized (class) name. Make the template argument of the vector of interest, the generalized name of the struct. Access each cell of the two dimensional structure with the syntax, vtr[i]. columnName.

Can I use vector in struct?

The vector is fine. Be aware that if you copy this struct, then the vector will be copied with it. So in code with particular performance constraints, treat this struct the same way that you'd treat any other expensive-to-copy type.

How do I get the size of a vector in C++?

To get the size of a C++ Vector, you can use size() function on the vector. size() function returns the number of elements in the vector.


1 Answers

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.

like image 75
Shepmaster Avatar answered Oct 19 '22 22:10

Shepmaster