I know that I can write a loop and do it but I wondered if there is a nicer way to do it?
You can use a Range iterator:
let v: Vec<i32> = (0..100).collect();
An alternate way to write this:
use std::iter::FromIterator;
let v = Vec::from_iter(0..100);
Uhh... That's nice. Thanks.
You can also use the Extend trait with a Range iterator if you already have a pre-allocated vec:
let mut v = Vec::with_capacity(100); // My pre-allocated vec from elsewhere
v.extend(0..100);
Keep in mind, collect and from_iter probably already preallocates the correct amount of it can, so it would be the same performance wise as what you've shown
I agree, in most cases (0..100).collect()
is better.
Using the Extend
trait is useful in cases where you're reusing a vector. For example, in a loop where you clear the vector every iteration:
let mut v: Vec::with_capacity(100);
for i in 0..10 {
v.extend(i..i+100);
dbg!(&v); // do stuff with v
v.clear();
}
I think I implied that what I said was based on whether the optimizer can see through something and was unpredictable
In fact, iirc it's very predictable, collect with allocate according to the lower bound of size_hint, so ranges have a very strict lower_bound and you'll get a single allocation always
Vec::iter also has a correct bound, and map() preserves that so that very common case is also single allocation
If it matter then use fold or look at the source of whatever iterator you're collecting to check it's size_hint
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.