簡體   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