问题描述
我有一个可选值的自定义可选迭代器。如果该值为 None
,我想提供一个 None
值的默认迭代器。但是,我无法获得匹配的类型。下面是一个 reduced example。有关如何处理此问题的任何建议?
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<_>>>`
解决方法
这取决于 x
应该是 Iterator
还是 Vec
。
迭代器
let x = i.into_iter().flatten().chain(iter::repeat(None)).take(3);
以下是每一步的解释:
-
into_iter()
从我们的Option
创建一个迭代器。我们的next()
调用将返回整个Vec
。 -
flatten
迭代Vec
及其所有元素 -
chain(iter::repeat(None))
向迭代添加无限的None
次 -
take(3)
将元素的总数限制为三个。
但是,这假设您希望始终只有三个元素,并且要么限制 Vec
,要么用 None
填充它。
矢量
由于 take(3)
返回一个迭代器,而 unwrap_or
在现有向量上返回一个 Vec
,我们需要通过 Vec
将迭代器转换为 collect()
:
let x = i.unwrap_or(iter::repeat(None).take(3).collect());
现在类型匹配了。