I want to create a Vec<T>
and make some room for it, but I don't know how to do it, and, to my surprise, there is almost nothing in the official documentation about this basic type.
let mut v: Vec<i32> = Vec<i32>(SIZE); // How do I do this ?
for i in 0..SIZE {
v[i] = i;
}
I know I can create an empty Vec<T>
and fill it with push
es, but I don't want to do that since I don't always know, when writing a value at index i
, if a value was already inserted there yet. I don't want to write, for obvious performance reasons, something like :
if i >= len(v) {
v.push(x);
} else {
v[i] = x;
}
And, of course, I can't use the vec!
syntax either.
In Rust, there are several ways to initialize a vector. In order to initialize a vector via the new() method call, we use the double colon operator: let mut vec = Vec::new();
Vec is a heap-allocated type with a great deal of scope for optimizing the number of allocations, and/or minimizing the amount of wasted space. To do this requires understanding how its elements are stored. A Vec contains three words: a length, a capacity, and a pointer.
Vector is a module in Rust that provides the container space to store values. It is a contiguous resizable array type, with heap-allocated contents. It is denoted by Vec<T>. Vectors in Rust have O(1) indexing and push and pop operations in vector also take O(1) complexity.
It means "Rust compiler, infer what type goes into the Vec ". And it is indeed analogous to the unused variable in Python (and in Rust itself), in that it represents a placeholder for a type, like it can represent a placeholder for a variable name.
While vec![elem; count]
from the accepted answer is sufficient to create a vector with all elements equal to the same value, there are other convenience functions.
Vec::with_capacity()
creates a vector with the given capacity but with zero length. It means that until this capacity is reached, push()
calls won't reallocate the vector, making push()
essentially free:
fn main() {
let mut v = Vec::with_capacity(10);
for i in 0..10 {
v.push(i);
}
println!("{:?}", v);
}
You can also easily collect()
a vector from an iterator. Example:
fn main() {
let v: Vec<_> = (1..10).collect();
println!("{:?}", v);
}
And finally, sometimes your vector contains values of primitive type and is supposed to be used as a buffer (e.g. in network communication). In this case you can use Vec::with_capacity()
+ set_len()
unsafe method:
fn main() {
let mut v = Vec::with_capacity(10);
unsafe { v.set_len(10); }
for i in 0..10 {
v[i] = i;
}
println!("{:?}", v);
}
Note that you have to be extra careful if your vector contains values with destructors or references - it's easy to get a destructor run over a uninitialized piece of memory or to get an invalid reference this way. It will also work right if you only use initialized part of the vector (you have to track it yourself now). To read about all the possible dangers of uninitialized memory, you can read the documentation of mem::uninitialized()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With