Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a vector of received size?

Tags:

rust

I have a vector data with size unknown at compile time. I want to create a new vector of the exact that size. These variants don't work:

let size = data.len();

let mut try1: Vec<u32> = vec![0 .. size]; //ah, you need compile-time constant
let mut try2: Vec<u32> = Vec::new(size); //ah, there is no constructors with arguments

I'm a bit frustrated - there is no any information in Rust API, book, reference or rustbyexample.com about how to do such simple base task with vector. This solution works but I don't think it is good to do so, it is strange to generate elements one by one and I don't have need in any exact values of elements:

let mut temp: Vec<u32> = range(0u32, data.len() as u32).collect();
like image 898
Arsenii Fomin Avatar asked Jan 29 '15 06:01

Arsenii Fomin


People also ask

How do I make a vector a specific size?

To create a vector of specified data type and length in R we make use of function vector(). vector() function is also used to create empty vector.

What is the size of a vector?

The size of a vector is the number of elements that it contains, which is directly controlled by how many elements you put into the vector. Capacity is the amount of total space that the vector has. Under the hood, a vector just uses an array. The capacity of the vector is the size of that array.

How do you reserve the size of a vector?

std::vector class provides a useful function reserve which helps user specify the minimum size of the vector.It indicates that the vector is created such that it can store at least the number of the specified elements without having to reallocate memory. Each vector object has two parameters–size and capacity.


2 Answers

The recommended way of doing this is in fact to form an iterator and collect it to a vector. What you want is not precisely clear, however; if you want [0, 1, 2, …, size - 1], you would create a range and collect it to a vector:

let x = (0..size).collect::<Vec<_>>();

(range(0, size) is better written (0..size) now; the range function will be disappearing from the prelude soon.)

If you wish a vector of zeroes, you would instead write it thus:

let x = std::iter::repeat(0).take(size).collect::<Vec<_>>();

If you merely want to preallocate the appropriate amount of space but not push values onto the vector, Vec::with_capacity(capacity) is what you want.

You should also consider whether you need it to be a vector or whether you can work directly with the iterator.

like image 81
Chris Morgan Avatar answered Sep 21 '22 15:09

Chris Morgan


You can use Vec::with_capacity() constructor followed by an unsafe set_len() call:

let n = 128;
let v: Vec<u32> = Vec::with_capacity(n);
unsafe { v.set_len(n); }
v[12] = 64;  // won't panic

This way the vector will "extend" over the uninitialized memory. If you're going to use it as a buffer it is a valid approach, as long as the type of elements is Copy (primitives are ok, but it will break horribly if the type has a destructor).

like image 21
Vladimir Matveev Avatar answered Sep 18 '22 15:09

Vladimir Matveev