最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

rust 自定義迭代器的實(shí)現(xiàn)方法

 更新時(shí)間:2026年01月08日 10:39:50   作者:碼事漫談  
本文介紹了Rust中的迭代器概念、IteratorTrait及其實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 什么是迭代器???

簡單來說,迭代器就是一個(gè)“知道如何獲取下一個(gè)元素”的東西。

它是一種設(shè)計(jì)模式,允許你遍歷一個(gè)序列(比如數(shù)組、列表或你自定義的任何東西),而不需要關(guān)心序列內(nèi)部是怎么存儲(chǔ)的。

在 Rust 中,你最常見的迭代器用法就是 for 循環(huán):r` 循環(huán):

let numbers = vec![1, 2, 3];

// 這里的 `numbers.iter()` 就創(chuàng)建了一個(gè)迭代器
for num in numbers.iter() {
    println!("Got: {}", num);
}

for 循環(huán)就是不斷地問這個(gè)迭代器:“嘿,還有下一個(gè)嗎?有的話請(qǐng)給我。” 直到迭代器回答:“抱歉,沒有了。”

我們的目標(biāo)就是學(xué)會(huì)如何創(chuàng)造這種“東西”。

2. 核心揭秘:IteratorTrait

在 Rust 中,“迭代器”并不是一個(gè)具體的類型,而是**任何了 Iterator Trait 的類型**。

這個(gè) Trait (特質(zhì)) 的定義簡化后是這樣的:

pub trait Iterator {
    // 1. 關(guān)聯(lián)類型:告訴 Rust 你迭代的“東西”是什么類型
    type Item; 

    // 2. 核心方法:獲取下一個(gè)元素
    // 這是你唯一必須實(shí)現(xiàn)的方法!
    fn next(&mut self) -> Option<Self::Item>;

    // --- 下面還有很多其他方法 (map, filter, sum...) ---
    // 但它們都有默認(rèn)實(shí)現(xiàn),你暫時(shí)不用管!
}

是不是看起來很簡單?我們來拆解一下你必須關(guān)心的兩個(gè)部分:

type Item;

這是一個(gè)關(guān)聯(lián)類型。你只需要告訴 Rust:“我這個(gè)迭代器,每次‘吐’出來的元素是 i32 類型”或者“是 String 類型”。

例如:type Item = u32; 或 type Item = &String;

fn next(&mut self) -> Option<Self::Item>

這就是魔法發(fā)生的地方!??

  • &mut self:為什么是 &mut (可變借用)?因?yàn)榈餍枰?*狀態(tài)**。比如,一個(gè)計(jì)數(shù)器需要知道“我當(dāng)前數(shù)到幾了”,每次調(diào)用 next 之后,這個(gè)狀態(tài)就要改變(比如 +1)。

  • Option<Self::Item>:這是迭代器設(shè)計(jì)的精髓!

    • **`Some(ue)**:如果序列中還有下一個(gè)元素,就返回 Some(那個(gè)元素)`。
    • None:如果序列已經(jīng)結(jié)束了,就返回 None。for 循環(huán)看到 None 就會(huì)自動(dòng)停止。

3. 實(shí)踐一:你的第一個(gè)迭代器 (簡單的計(jì)數(shù)器) ??

我們來寫一個(gè)最簡單的迭代器:一個(gè)從 1 數(shù)到 5 的計(jì)數(shù)器。

第 1 步:定義結(jié)構(gòu)體 (保存狀態(tài))

迭代器需要“記憶”,所以我們需要一個(gè)結(jié)構(gòu)體來保存它的“狀態(tài)”。對(duì)于計(jì)數(shù)器,我們需要知道“當(dāng)前數(shù)到幾了” (current) 和“什么時(shí)候停” (max)。

// 我們的計(jì)數(shù)器結(jié)構(gòu)體
struct Counter {
    current: u32,
    max: u32,
}

// 順便給它一個(gè) "構(gòu)造函數(shù)" (new)
impl Counter {
    fn new(max: u32) -> Counter {
        Counter { current: 1, max } // 我們從 1 開始數(shù)
    }
}

第 2 步:實(shí)現(xiàn)IteratorTrait

現(xiàn)在,我們來告訴 Rust 如何讓 Counter 變成一個(gè)迭代器。

impl Iterator for Counter {
    // 1. 告訴 Rust 我們迭代的是 u32
    type Item = u32;

    // 2. 實(shí)現(xiàn)核心邏輯!
    fn next(&mut self) -> Option<Self::Item> {
        if self.current <= self.max {
            // 只要當(dāng)前值 <= 5
            
            // 準(zhǔn)備好要返回的當(dāng)前值
            let val_to_return = self.current; 
            
            // 更新狀態(tài):讓 current + 1,為下一次做準(zhǔn)備
            self.current += 1; 

            // 把值用 Some() 包裹起來返回
            Some(val_to_return)
        } else {
            // 如果 current 已經(jīng) > max (比如到了 6)
            // 迭代結(jié)束!返回 None
            None
        }
    }
}

第 3 步:使用它!

恭喜你!你已經(jīng)寫好了一個(gè)完整的迭代器!?? 讓我們用用看:

fn main() {
    let counter = Counter::new(5); // 創(chuàng)建一個(gè) 1 到 5 的計(jì)數(shù)器

    // `for` 循環(huán)現(xiàn)在可以識(shí)別我們的 Counter 了!
    println!("Running for loop:");
    for number in counter {
        println!("{}", number);
    }
    
    // 注意:`for` 循環(huán)會(huì)“消耗掉”迭代器。
    // 如果想再用一次,需要重新創(chuàng)建:
    let counter2 = Counter::new(3);
    
    // 你也可以手動(dòng)調(diào)用 next() 看看發(fā)生了什么
    println!("\nManual next() calls:");
    let mut counter3 = Counter::new(2); // 必須是 mut,因?yàn)?next() 需要 &mut self
    println!("{:?}", counter3.next()); // Some(1)
    println!("{:?}", counter3.next()); // Some(2)
    println!("{:?}", counter3.next()); // None (迭代結(jié)束)
    println!("{:?}", counter3.next()); // None (之后永遠(yuǎn)是 None)
}

輸出:

Running for loop:
1
2
3
4
5

Manual next() calls:
Some(1)
Some(2)
None
None

你已經(jīng)掌握了 80% 的精髓了!太棒了!??

4. 實(shí)踐二:讓自定義結(jié)構(gòu)體“可迭代” ??

在實(shí)踐一中,Counter 本身就是迭代器。但更常見的情況是:你有一個(gè)集合(比如 `Myook),你想**為它創(chuàng)建一個(gè)迭代器**(比如 BookPageIterator`)。

就像 Vec (集合) 和 VecIter (它的迭代器) 的關(guān)系一樣。

我們希望實(shí)現(xiàn)這樣的效果:

let my_list = MyList::new();
for item in &my_list { // 注意這里是 &my_list
    // ...
}

要實(shí)現(xiàn)這個(gè),我們需要兩個(gè) Trait:Iterator (老朋友) 和 IntoIterator (新朋友)。

IntoIterator Trait 就像一個(gè)“轉(zhuǎn)換器”,它告訴 for 循環(huán):“嘿,我知道如何把我(&MyList)轉(zhuǎn)換成一個(gè)真正的迭代器!”

第 1 步:定義集合和它的迭代器結(jié)構(gòu)體

// 我們的集合
struct MyList {
    items: Vec<String>,
}

impl MyList {
    fn new() -> Self {
        Self {
            items: vec![
                "Rust".to_string(),
                "is".to_string(),
                "Awesome".to_string(),
            ],
        }
    }
}

// ------------------------------------
// 專門為 MyList 服務(wù)的迭代器結(jié)構(gòu)體
// 它需要“借用” MyList 的數(shù)據(jù)
// 'a 是生命周期,表示它借用的數(shù)據(jù)至少和 'a 活得一樣久
struct MyListIter<'a> {
    list: &'a MyList, // 持有對(duì) MyList 的引用
    index: usize,    // 跟蹤迭代到第幾個(gè)了
}

第 2 步:為 `MyListIter 實(shí)現(xiàn)Iterator

這和 Counter 的例子幾乎一樣,只是現(xiàn)在我們是從 Vec 中取數(shù)據(jù)。

// 'a 也要在這里聲明
impl<'a> Iterator for MyListIter<'a> {
    // 這一次,我們迭代的是對(duì) String 的引用
    type Item = &'a String;

    fn next(&mut self) -> Option<Self::Item> {
        if self.index < self.list.items.len() {
            // 還有元素
            let item = &self.list.items[self.index];
            self.index += 1;
            Some(item)
        } else {
            // 沒元素了
            None
        }
    }
}

第 3 步:關(guān)鍵!為MyList實(shí)現(xiàn)IntoIterator

這是連接 for 循環(huán)和 MyListIter 的“膠水”。我們希望 for item in &my_list 能工作,所以我們要為 &MyList 實(shí)現(xiàn) IntoIterator

// 為 &MyList (對(duì) MyList 的不可變引用) 實(shí)現(xiàn) IntoIterator
impl<'a> IntoIterator for &'a MyList {
    // 迭代項(xiàng)還是 &String
    type Item = &'a String; 
    
    // 告訴 for 循環(huán):你調(diào)用 into_iter() 時(shí),
    // 我會(huì)返回一個(gè) MyListIter<'a> 實(shí)例
    type IntoIter = MyListIter<'a>; 

    // `for` 循環(huán)會(huì)自動(dòng)調(diào)用這個(gè)方法!
    // 這里的 self 就是 &'a MyList
    fn into_iter(self) -> Self::IntoIter {
        // 創(chuàng)建我們剛才定義的迭代器實(shí)例
        MyListIter {
            list: self, // self 就是 &MyList
            index: 0,   // 從 0 開始
        }
    }
}

第 4 步:見證奇跡!

fn main() {
    let my_list = MyList::new();
    
    // 感謝 IntoIterator,這行代碼現(xiàn)在可以完美工作了!
    // 1. `for` 循環(huán)看到 &my_list
    // 2. 它調(diào)用 (&my_list).into_iter()
    // 3. 我們的代碼返回了一個(gè) MyListIter
    // 4. `for` 循環(huán)不斷調(diào)用 MyListIter.next()
    for item in &my_list {
        println!("Item: {}", item);
    }
}

輸出:

Item: Rust
Item: is
Item: Awesome

你做到了!這已經(jīng)是 Rust 中非常地道的迭代器實(shí)現(xiàn)方式了!??

5. 你免費(fèi)獲得的“超能力” ??

最爽的部分來了!

當(dāng)你辛辛苦苦地實(shí)現(xiàn)了 Iterator Trait(哪怕只寫了 next() 方法),Rust 編譯器會(huì)免費(fèi)贈(zèng)送給你一大堆超級(jí)好用的“迭代器適配器” (Iterator Adapters)!

比如 .map(), .filter(), .zip(), .sum(), .collect()… 全都能用了!

看看我們剛才的 Counter

let sum: u32 = Counter::new(5)     // 我們的迭代器 (1, 2, 3, 4, 5)
    .zip(Counter::new(5).skip(1)) // ( (1,2), (2,3), (3,4), (4,5) )
    .map(|(a, b)| a * b)          // ( 2, 6, 12, 20 )
    .filter(|x| *x > 10)         // ( 12, 20 )
    .sum();                      // 12 + 20 = 32

println!("The complex sum is: {}", sum); // 32

我們只寫了 next(),但 zip, skip, map, filter, sum 都能在我們的 Counter 上使用!這就是 Rust Trait 和迭代器模式的強(qiáng)大之處!

6. 總結(jié) & 下一步

我們來回顧一下關(guān)鍵點(diǎn):

  1. 迭代器是任何實(shí)現(xiàn)了 Iterator Trait 的東西。
  2. Iterator Trait 的核心是 type Item; (迭代什么) 和 `fn next(&mut self) -> OptionSelf::Item 你需要一個(gè) struct 來保存迭代的狀態(tài) (比如 current 索引)。
  3. `next)方法通過返回Some(value)來提供值,通過返回None` 來停止迭代。
  4. 要讓你自己的集合(如 MyList)支持 for item in &collection,你需要為 &collection 實(shí)現(xiàn) IntoIterator Trait,讓它返回你自定義的迭代器(如 MyListIter)。
  5. 一旦實(shí)現(xiàn)了 Iterator,你就免費(fèi)獲得了所有適配器 (map, `filter …)。

到此這篇關(guān)于rust 自定義迭代器的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)rust 自定義迭代器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入了解Rust的生命周期

    深入了解Rust的生命周期

    生命周期指的是引用保持有效的作用域,Rust的每個(gè)引用都有自己的生命周期。本文將通過示例和大家詳細(xì)說說Rust的生命周期,需要的可以參考一下
    2022-12-12
  • Rust語言從入門到精通之Tokio的Channel深入理解

    Rust語言從入門到精通之Tokio的Channel深入理解

    這篇文章主要為大家介紹了Rust語言從入門到精通之Tokio的Channel深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Rust語言之trait中的個(gè)方法可以重寫嗎

    Rust語言之trait中的個(gè)方法可以重寫嗎

    在Rust中,trait定義了一組方法,這些方法可以被一個(gè)或多個(gè)類型實(shí)現(xiàn),當(dāng)你為某個(gè)類型實(shí)現(xiàn)一個(gè)trait時(shí),你可以為該trait中的每個(gè)方法提供自己的具體實(shí)現(xiàn),本文將給大家介紹一下trait中的個(gè)方法是否可以重寫,需要的朋友可以參考下
    2023-10-10
  • Rust練習(xí)冊(cè)之字母異位詞與字符串處理方法技巧

    Rust練習(xí)冊(cè)之字母異位詞與字符串處理方法技巧

    Rust作為一種系統(tǒng)編程語言,其在字符串拼接方面的設(shè)計(jì)既靈活又高效,這篇文章主要介紹了Rust練習(xí)冊(cè)之字母異位詞與字符串處理方法技巧的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-02-02
  • Rust突破編譯器限制構(gòu)造可修改的全局變量

    Rust突破編譯器限制構(gòu)造可修改的全局變量

    這篇文章主要為大家介紹了Rust突破編譯器限制構(gòu)造可修改的全局變量示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Rust裸指針的安全性實(shí)例講解

    Rust裸指針的安全性實(shí)例講解

    裸指針是一個(gè)不包含所有權(quán)和借用關(guān)系的原始指針,它們與常規(guī)指針相比沒有任何限制和保護(hù)措施,這篇文章主要介紹了Rust裸指針的安全性實(shí)例,需要的朋友可以參考下
    2023-05-05
  • 深入了解Rust中的枚舉和模式匹配

    深入了解Rust中的枚舉和模式匹配

    這篇文章主要為大家詳細(xì)介紹了Rust中的枚舉和模式匹配的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Rust 語言中的 into() 方法及代碼實(shí)例

    Rust 語言中的 into() 方法及代碼實(shí)例

    在 Rust 中,into() 方法通常用于將一個(gè)類型的值轉(zhuǎn)換為另一個(gè)類型,這通常涉及到資源的所有權(quán)轉(zhuǎn)移,本文給大家介紹Rust 語言中的 into() 方法及代碼實(shí)例,感謝的朋友跟隨小編一起看看吧
    2024-03-03
  • Rust如何使用線程同時(shí)運(yùn)行代碼

    Rust如何使用線程同時(shí)運(yùn)行代碼

    Rust使用1:1線程模型,通過std::thread::spawn創(chuàng)建線程,返回JoinHandle用于等待線程完成,閉包默認(rèn)借用外部變量,使用move關(guān)鍵字轉(zhuǎn)移所有權(quán),多線程共享數(shù)據(jù)時(shí)需使用并發(fā)原語,如Mutex、RwLock、Arc等,以避免競態(tài)條件
    2025-02-02
  • Rust語言之使用Polar權(quán)限管理方法詳解

    Rust語言之使用Polar權(quán)限管理方法詳解

    權(quán)限管理 (Permission Management) 是一個(gè)涵蓋了系統(tǒng)或網(wǎng)絡(luò)中用戶權(quán)限控制和管理的系統(tǒng),本文將詳細(xì)給大家介紹Rust語言中如何使用Polar權(quán)限管理,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

太和县| 泾川县| 天祝| 军事| 故城县| 工布江达县| 寿阳县| 江门市| 河间市| 遂溪县| 杭州市| 禹州市| 天气| 霍林郭勒市| 武山县| 棋牌| 吉木乃县| 芒康县| 富平县| 沽源县| 青海省| 南靖县| 平顺县| 宣城市| 蛟河市| 南投县| 满城县| 伊川县| 三亚市| 闻喜县| 新乡市| 广州市| 时尚| 新和县| 获嘉县| 墨脱县| 穆棱市| 孝义市| 洮南市| 乌兰县| 嘉义县|