[英]Implementing a custom Iterator Trait
源代码
pub struct Iterating_ex {
start: u32,
end: u32,
}
impl Iterator for Iterating_ex {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.start >= self.end {
None
} else {
let result = Some(self.start);
self.start += 1;
result
}
}
}
fn main() {
let example = Iterating_ex {
start: 0,
end: 5,
};
for i in example {
println!("{i}");
}
}
Output
0
1
2
3
4
我个人理解每段代码试图做什么,但是我无法理解以下内容,可能是由于我缺乏对通用迭代器特性的理解;
example
上使用 for 循环。next
方法被称为循环,直到返回None
。 代码如何知道这样做? 广告 1 。 在 rust 中成为“可迭代的”意味着实现Iterator
特性。 然而,有些东西可以变成迭代器,这由另一个特征IntoIterator
描述。 标准库提供了全面的实施:
impl<I: Iterator> IntoIterator for I { /* ... */}
这意味着任何实现Iterator
的类型都可以变成一个(它是 noop)。 for
循环旨在与实现IntoIterator
的类型一起使用。 这就是为什么你可以这样写:
let mut v = vec![1, 2, 3, 4, 5];
for _ in &v {}
for _ in &mut v {}
for _ in v {}
由于类型&Vec<T>
、 &mut Vec<T>
和Vec<T>
都实现IntoIterator
特性。 当然,它们都变成了不同的迭代器类型,并分别返回&T
、 &mut T
和T
。
广告 2 。 如前所述,for 循环可用于实现IntoIterator
的类型。 文档详细解释了它是如何工作的,但简而言之for
循环只是一个语法糖,可以转换这段代码:
for x in xs {
todo!()
}
进入这样的事情:
let mut xs_iter = xs.into_iter();
while let Some(x) = xs_iter.next() {
todo!()
}
while
循环也是语法糖,并通过break
语句将糖分转化为loop
,但这与此处无关。
边注。 我想这只是一个学习示例,它很棒,但是标准库中已经存在与std::ops::Range
完全相同的迭代器,因此如果需要,请将其用作您的实际代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.