英文:
How does flatten behave diffrently with Vec<Vec<_>> and Vec<Result<T<E>> or Vec<Option<T>> in rust
问题
The official docs of iter::flatten state:
> 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 using entries.flatten()
instead of the if-let
block. However, in this context, there is no "nesting." 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 does flatten
do here? How does it work?
英文:
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?
答案1
得分: 2
>但这里并没有"嵌套",而是一个结果的迭代器
但是,Result
实现了IntoIterator
。这意味着你实际上有嵌套的迭代器...或者说,嵌套的项目_可以转化为迭代器_,这就是Iterator::flatten()
对于迭代器项的所有要求:
where Self::Item: IntoIterator
Result<T, E>
的实现在Ok
时产生包含的T
,在Err
时不产生任何项。因此,Clippy是正确的--你可以使用Iterator::flatten
来简化这段代码。
对于Option<T>
也是一样的。当转换为迭代器时,如果是Some
,它将产生包含的T
,如果是None
,则不产生任何项。
英文:
>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
.
答案2
得分: 0
Result
也实现了 IntoIterator
,具有一个迭代器,在 Ok
情况下产生一个元素,在 Err
情况下不产生任何元素,因此它有效。
英文:
Result
also implements IntoIterator
, with an iterator that yields one element in the Ok
case and nothing in the Err
case, so it works.
答案3
得分: 0
"所以我的问题是,这里的flatten到底是做什么的?它是如何工作的?
fn flatten(self) -> Flatten<Self> where
Self: Sized,
Self::Item: IntoIterator
所以flatten将主题迭代器的项目"链"在一起,如果它们是可迭代的(IntoIterator
)。
Result
和 Option
实现了 IntoIterator
,行为类似于具有值或无值/错误的0..=1元素的迭代器(取决于结果/选项是否具有值)。
因此,如果有值,它只是将Result替换为其项目(Ok
),否则它会被剥离。这基本上就是你在这里做的事情,因此建议使用clippy。"
英文:
> So my question is what exactly flatten do here? How does it work?
fn flatten(self) -> Flatten<Self> where
Self: Sized,
Self::Item: IntoIterator
So flatten "chains" the items of the subject iterator if they are iterable (IntoIterator
).
Result
and Option
implement IntoIterator
, behaving as iterators of 0..=1 elements (depending whether the result/option has a value or a none/error).
So it just replaces the Result by its item (Ok
) if there is one, otherwise it's stripped. Which is essentially what you're doing here, hence the recommendation of clippy.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论