繁体   English   中英

实现自定义 Iterator Trait

[英]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

我个人理解每段代码试图做什么,但是我无法理解以下内容,可能是由于我缺乏对通用迭代器特性的理解;

  1. 为结构实现 Iterator 特性会自动生成可迭代数据类型吗? 在这种情况下,我不知道为什么可以在example上使用 for 循环。
  2. 似乎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 TT

广告 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM