How can I make a Vec containing [0,1,2,3,4,3,2,1,0] using ranges?
I tried this:
let mut a = vec![0..len];
let b = vec![len..=0];
a.extend(&b);
But it raises an error:
type mismatch resolving `<&Vec<RangeInclusive<usize>> as IntoIterator>::Item == std::ops::Range<usize>`
>Solution :
There’s no direct syntax that I know of to create a Vec directly from a range. A range is an first-class object and implements Iterator, so you can collect a range into a Vec.
Ranges must also be from low to high. To get a reversed range create a regular forward range and call rev to create an iterator that iterates in reverse.
let mut a = (0..len).collect::<Vec<_>>();
let b = (0..=len).rev();
a.extend(&b);
You’ll notice that collect requires ::<>, the so-called turbofish operator. That’s because it’s a generic method that can convert an iterator into any type that implements FromIterator. There are many collection types that implement FromIterator, so we must tell it we want a Vec in particular.
Declaring a‘s type would have also worked:
let mut a: Vec<_> = (0..len).collect();
let b = (0..=len).rev();
a.extend(&b);
It’s also possible to construct the vector in place by chaining the two iterators together and then collecting the result. This way a doesn’t need to be mut.
let a = (0..len).chain((0..=len).rev())
.collect::<Vec<_>>();