gpt4 book ai didi

iterator - 有条件地从 flat_map 返回空迭代器

转载 作者:行者123 更新时间:2023-11-29 07:47:38 26 4
gpt4 key购买 nike

给定 foo 的定义:

let foo = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];

我希望能够编写这样的代码:

let result: Vec<_> = foo.iter()
.enumerate()
.flat_map(|(i, row)| if i % 2 == 0 {
row.iter().map(|x| x * 2)
} else {
std::iter::empty()
})
.collect();

但这会引发有关 if 和 else 子句具有不兼容类型的错误。我尝试暂时删除 map 并尝试在闭包外部定义一个空向量并返回一个迭代器,如下所示:

let empty = vec![];

let result: Vec<_> = foo.iter()
.enumerate()
.flat_map(|(i, row)| if i % 2 == 0 {
row.iter() //.map(|x| x * 2)
} else {
empty.iter()
})
.collect();

这看起来有点傻,但它可以编译。如果我尝试取消对 map 的注释,它仍然会提示 if 和 else 子句具有不兼容的类型。这是错误消息的一部分:

error[E0308]: if and else have incompatible types
--> src/main.rs:6:30
|
6 | .flat_map(|(i, row)| if i % 2 == 0 {
| ______________________________^
7 | | row.iter().map(|x| x * 2)
8 | | } else {
9 | | std::iter::empty()
10 | | })
| |_________^ expected struct `std::iter::Map`, found struct `std::iter::Empty`
|
= note: expected type `std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:7:28: 7:37]>`
found type `std::iter::Empty<_>`

Playground Link

我知道我可以通过一些嵌套的 for 循环编写一些我想要的东西,但我想知道是否有一种使用迭代器编写它的简洁方法。

最佳答案

由于 Rust 是静态类型的,并且迭代器链中的每个步骤都会将结果更改为包含先前类型的新类型(除非您使用盒装特征对象),因此您必须以两个分支都涵盖的方式编写它相同的类型。

用单一类型传达条件空虚的一种方法是 TakeWhile迭代器实现。

.flat_map(|(i, row)| {
let iter = row.iter().map(|x| x * 2);
let take = i % 2 == 0;
iter.take_while(|_| take)
})

如果您不介意忽略输入迭代器 foo 可能包含多个 usize 元素的边缘情况,您也可以使用 Take 而不是 0 或 usize::MAX。它具有提供比 TakeWhile 更好的 size_hint() 的优势。

关于iterator - 有条件地从 flat_map 返回空迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45787053/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com