Reputation: 334
I have a custom optional iterator of optional values. If that value is None
I would like to provide a default iterator of None
values. However, I cannot get the types to match. Below is a reduced example. Any suggestions of how to handle this?
use std::iter;
fn main() {
let i = Some(vec![Some(1), Some(2), Some(3)]);
let x = i.unwrap_or(iter::repeat(None).take(3));
for y in x {
println!("{:?}", y);
}
}
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:5:25
|
5 | let x = i.unwrap_or(iter::repeat(None).take(3));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Vec`, found struct `std::iter::Take`
|
= note: expected struct `Vec<Option<{integer}>>`
found struct `std::iter::Take<std::iter::Repeat<Option<_>>>`
Upvotes: 0
Views: 1020
Reputation: 105965
It depends whether x
should be an Iterator
or a Vec
.
let x = i.into_iter().flatten().chain(iter::repeat(None)).take(3);
Here's every step explained:
into_iter()
creates an iterator from our Option
. Our next()
call would return the whole Vec
.flatten
iterates the Vec
and thus all its elementschain(iter::repeat(None))
adds unlimited None
s to the iterationtake(3)
limits the total amount of elements to three.However, this assumes that you want to have exactly three elements always and either limit the Vec
or fill it up with None
s.
Since take(3)
returns an iterator, but unwrap_or
returns a Vec
on an existing vector, we need to transform the iterator into a Vec
via collect()
:
let x = i.unwrap_or(iter::repeat(None).take(3).collect());
Now the types match.
Upvotes: 1