Often it is more practical to work with a kind of array than can grow (or shrink) in size because it is allocated on the heap. Rust provides this through the vector type Vec, from the module std::vec. This is a generic type, which means that the items can have any type T, where T is specified in the code; for example we can have Vec<i32> or Vec<&str> vector types. To indicate that it is a generic type, it is written as Vec<T>, where all elements must be of the same type T.
We can make a vector in either of two ways, with the function new() or with the macro vec!:
let mut numbers: Vec<i32> = Vec::new(); let mut magic_numbers = vec![7i32, 42, 47, 45, 54];
In the first case the type is indicated explicitly with the vector type Vec<i32>, in the second case this is done by giving the first item an i32 suffix, but this is usually optional.
We can also make a new vector with an initial memory size allocated to it, which can be useful if you know in advance that you will need at least that many items. The following initializes a vector for signed integers, with memory allocated for 25 integers:
let mut ids: Vec<i32> = Vec::with_capacity(25);
We need to provide the type here, otherwise the compiler can not calculate the amount of memory needed.
A vector can also be constructed from an Iterator through the method collect(), like in this example with a range:
let rgvec: Vec<u32> = (0..7).collect(); println!("Collected the range into: {:?}", rgvec);
This prints the following output:
Collected the range into: [0, 1, 2, 3, 4, 5, 6]
Indexing, getting the length and looping over a vector works the same as with arrays. For example, a for loop over a vector can be written simply as:
let values = vec![1, 2, 3]; for n in values { println!("{}", n); }
This prints out the following output on consecutive lines:
1 2 3
Add a new item to the end of a vector with the function push(), and remove the last item with the function pop().
numbers.push(magic_numbers[1]); numbers.push(magic_numbers[4]); println!("{:?}", numbers); // [42, 54] let fifty_four = numbers.pop();// fifty_four now contains 54 println!("{:?}", numbers); // [42]
If you need to mutate the vector while iterating, use iter_mut:
let mut vec = vec![1, 2, 3, 4]; for x in vec.iter_mut() { *x += 1; } println!("Mutated vector: {:?}", vec);
This prints out the following output:
Mutated vector: [2, 3, 4, 5]
The x variable here is a reference to the successive items of the vector, to obtain its value you must use the dereferencing operator *.
If you omit the *, you get the following error:
error[E0368]: binary assignment operation '+=' cannot be applied to type '&mut {integer}'
If a function needs to return many values of the same type, make an array or vector with these values and return that object.