iter::flatten的官方文档指出:
一个迭代器,它将可转换为迭代器的内容的迭代器中的一个嵌套级别展平。
但对于此代码:
if let Ok(entries) = fs::read_dir("/path/to/dir") {
for entry in entries {
if let Ok(entry) = entry {
// Do something
}
}
}
Clippy建议使用entries.flatten()
而不是if-let
块,但这里没有“嵌套”,而是结果的迭代器。“嵌套”看起来像迭代器的迭代器。fs::read_dir()
返回的ReadDir中没有独占的flatten()
方法实现
所以我的问题是flatten在这里到底做了什么?它是如何工作的?
3条答案
按热度按时间knsnq2tg1#
但是这里没有“嵌套”,而是一个结果的迭代器
啊,但是
Result
实现了IntoIterator
。这意味着你实际上有嵌套的迭代器......或者更确切地说,嵌套的项 * 可以转换成迭代器 *,这是Iterator::flatten()
对迭代器项的所有要求:Result<T, E>
的实现在Ok
时产生包含的T
,而在Err
时不产生任何项。因此,clippy是正确的--您可以使用Iterator::flatten
来简化此代码。对于
Option<T>
也是如此。当转换为迭代器时,当Some
时,它将产生包含的T
,而当None
时,没有项目。cyej8jka2#
Result
也实现了IntoIterator
,它有一个迭代器,在Ok
的情况下只产生一个元素,而在Err
的情况下不产生任何元素,所以它可以工作。wqsoz72f3#
所以我的问题是flatten在这里到底做了什么?它是如何工作的?
因此,如果主题迭代器的项是可迭代的(
IntoIterator
),则扁平化“链”这些项。Result
和Option
实现了IntoIterator
,表现为0..=1个元素的迭代器(取决于result/option是否有值或none/error)。因此,如果有一个项(
Ok
),它就用它的项(Ok
)替换Result,否则它就被剥离了。