Initialize vector using vec! macro and fill it with values from existing array
Asked Answered
P

3

9

How can I initialize new Vector using the vec! macro and automatically fill it up with values from an existing array? Here's the code example:

let a = [10, 20, 30, 40]; // a plain array
let v = vec![??];       // TODO: declare your vector here with the macro for vectors

What can I fill in (syntax wise) instead of the ??? characters?

Platy answered 11/1, 2022 at 16:7 Comment(6)
Vec implements From<[T; N]>.Strawboard
@ネロク thanks for your comment, but since I am very new to the language, I have no idea what it means. Could you please explain it a little bit?Platy
You don't need the macro. let v = a.to_vec();Irma
@AdamComer thanks, however the example in rustlings implies that you should use the vec! macro (and I would like to learn it as well)Platy
According to the stdlib vec docs, the vec![] can't create a new Vec from a Slice.Irma
@ChayimFriedman I'm asking how to use it. I would like to initilize a new vector using this macro. This new vector should copy into itself the same values as the a array. (I'm coming from c# background where there are no macros, so there is a possibility that I have poor understanding of macros)Platy
O
12

Since Vec<T> impls From<[T; N]>, it can be created from an array by using the From::from() method or the Into::into() method:

let v = Vec::from(a);
// Or
let v: Vec<_> = a.into(); // Sometimes you can get rid of the type annoation if the compiler can infer it

The vec![] macro is not intended for that; it is intended for creating Vecs from scratch, like array literals. Instead of creating an array and converting it, you could use the vec![] macro:

let v = vec![10, 20, 30, 40];
Obola answered 11/1, 2022 at 16:21 Comment(0)
M
6

You can also use the to_vec method:

let a = [10, 20, 30, 40]; // a plain array
let v = a.to_vec(); 

Playground

A per the comments, notice that it clones the elements, so the vector items should implement Clone.

Multiplicate answered 11/1, 2022 at 16:24 Comment(7)
While it works, it clones the element, meaning redundant copies + a T: Clone requirement. This is because this methods operates on slices, and not arrays.Obola
Nice point, let me add that information as part of the answer though.Multiplicate
What is the difference between the a.to_vec() and Vec::from(a)? To be exact, why does it matter that the a.to_vec clones the element?Platy
@TDiblik, it do matters, if instead of creating a copy (as here) of the items you just transform (take ownership) of the underlaying memmory from the original array, usually is more efficient (Imagine a huuuge array, it is always easier not to spend resources on copying it).Multiplicate
Oh, ok, and if I take ownership of the underlying data, will I be able to use the a variable again (for example return it from function and push some new data to it)?Platy
@TDiblik, no, you will not be able to use a again. From/Into takes ownership of it (self). If you need to have both is better to use to_vec.Multiplicate
Ok, thanks, that's exactlly what I needed to hear! You guys have been so helpfull btw <3Platy
F
1

I'm new to rust.

I think the question comes from rustlings / exercises / vecs that help understand basic syntax for rust.

fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; // a plain array
    let v = // TODO: declare your vector here with the macro for vectors

    (a, v)
}

When I try to solve the problem, I searched whether there is a way to enumerate all element in the existing array and use it to construct vector by using vec! macro. It is easy to use Vec::from. However, it's not macro but a function. Or the exercise does not make sense?

Fracture answered 25/1, 2023 at 6:56 Comment(1)
I had the same issue and found this post. I think there's a mistake in the rustlings instruction for the exercise. Or maybe it was a tricky way to make one look up for the documentation and search a bit... Anyway, the other answers to this post cover the case very well.Finch

© 2022 - 2024 — McMap. All rights reserved.