The official docs of iter::flatten states :
An iterator that flattens one level of nesting in an iterator of things that can be turned into iterators.
But for this code:
if let Ok(entries) = fs::read_dir("/path/to/dir") {
for entry in entries {
if let Ok(entry) = entry {
// Do something
}
}
}
Clippy suggests to use entries.flatten()
instead of if-let
block, But here "nesting" is not there, instead it's an Iterator of Results. "Nesting" would look like an Iterator of Iterators.
There's no exclusive flatten()
method implementation in ReadDir which is returned by fs::read_dir()
So my question is what exactly flatten do here? How does it work?
But here "nesting" is not there, instead it's an Iterator of Results
Ah, but Result
implements IntoIterator
. This means you do effectively have nested iterators... or rather, nested items that can be turned into an iterator which is all the bound on Iterator::flatten()
requires of an iterator's items:
where Self::Item: IntoIterator
The implementation for Result<T, E>
yields the contained T
when Ok
and yields no items when Err
. Therefore, clippy is correct -- you can use Iterator::flatten
to simplify this code.
And the same is true for Option<T>
. When converted to an iterator, it will yield the contained T
when Some
and no items when None
.