Editor's note: this question was asked before Rust 1.0 and some of the assertions in the question are not necessarily true in Rust 1.0. Some answers have been updated to address both versions.
I want to create a vector, but I only know the size I want the vector to be at runtime. This is how I'm doing it now (i.e. creating an empty, mutable vector, and adding vectors to it) :
fn add_pairs(pairs: ~[int]) -> ~[int] {
let mut result : ~[int] = ~[];
let mut i = 0;
while i < pairs.len() {
result += ~[pairs[i] + pairs[i + 1]];
i += 2;
}
return result;
}
This is how I want to do it (i.e., creating a vector and putting everything in it, instead of adding lots of vectors together):
fn add_pairs(pairs: ~[int]) -> ~[int] {
let number_of_pairs = pairs.len() / 2;
let result : ~[int, ..number_of_pairs];
let mut i = 0;
while i < pairs.len() {
result[i] = pairs[2 * i] + pairs[2 * i + 1];
i += 1;
}
return result;
}
Unfortunately, doing the above gives me something like:
error: expected constant expr for vector length: Non-constant path in constant expr
let result: ~[int, ..number_of_pairs];
^~~~~~~~~~~~~~~~~~~~~~~~
I get the impression that vectors have to have their size known at compile time (and so you need to set their size to a constant). Coming from a Java background, I'm confused! Is there a way to create a vector whose size you only know at runtime?
I'm using Rust 0.6.
In at least Rust 1.0, there is a
Vec::with_capacity()
function that handles this scenario.Example code:
There is no way to create an array of constant length with the length determined at runtime; only compile-time constant length arrays are allowed, so (variations of) your first method with
Vec<i32>
(previously~[int]
) is the only supported way. You could usevec![0; number_of_pairs]
to create a vector of the correct size and use the second part.There are many helper functions for what you are trying to do (using
while
directly Rust should be very rare):Or even
Docs:
chunks
,filter
,map
,collect
. (Thefilter
is just because the last element ofchunks
may have length 1.)Also note that adding two vectors allocates a whole new one, while
push
doesn't do this necessarily and is much faster (and.collect
is similar).In Rust version 1.0.0, they've made the
std::vec:Vec
public structure stable so that you can instantiate a growable vector withlet mut my_vec = Vec::new();
You can also use thevec!
macro like so:let mut another_vec = vec![1isize, 2isize, 3isize];
What is important to note is that in both cases the variable you're assigning must be mutable.With these vectors you can call
my_vec.push(num);
for individual items oranother_vec.extend_from_slice(["list", "of", "objects"]);
to add items to the end of the vector.For your specific problem, you could do something like this:
You can see this in action on the Rust Playground where you have (what I assumed) was a nested vector of integer pairs.