色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

在Rust中實現Iterator和IntoIterator特征

jf_wN0SrCdH ? 來源:coding到燈火闌珊 ? 2023-07-02 10:01 ? 次閱讀

迭代器是一種強大的工具,它允許對數據結構進行有效的迭代,并且在許多編程語言中都實現了迭代器。然而,Rust獨特的所有權系統在如何實現和使用迭代器方面產生了有趣的差異。在本文中,我們將通過創建和實現最常用的迭代器特征——iterator和IntoIterator,來探索這些差異。

假設你有一個這樣的結構體:

pubstructTodos{
publist:Vec,
}

pubstructTodo{
pubmessage:String,
pubdone:bool,
}
如果我們希望遍歷這個Vec中的每個Todo,我們可以簡單地使用它的list屬性并遍歷它的元素,但是,如果我們想迭代Todos本身,而不暴露其內部屬性,該怎么辦呢?

Iterator

在Rust中,與Python等語言類似,迭代器是惰性的。這意味著除非對它們進行迭代(也就是消耗它們),否則它們是無效的。

letnumbers=vec![1,2,3];
letnumbers_iter=numbers.iter();
上面的代碼創建了一個迭代器——但沒有對它做任何操作。要使用迭代器,我們應該創建一個for循環,如下所示:
letnumbers=vec![1,2,3];
letnumbers_iter=numbers.iter();

fornumberinnumbers{
println!("{}",number)
}

還有其他方法可以用來創建迭代器。例如,每次在Rust中使用map()時,我們都在創建一個迭代器。

迭代器 vs 可迭代對象

如前所述,vector是一個可迭代對象。這意味著我們可以對它們進行迭代;但更準確地說,這意味著我們可以使用Vec來創建Iterator。例如,Vec可以生成一個迭代器,但它本身不是迭代器。

創建迭代器

讓我們回到Todos結構體看看我們如何創建一種方法來迭代它的元素。Todos有一個字段列表,它是一個Vec

在Rust中,Iterator是一個trait,其中包含一些方法,例如next(),它負責獲取集合的下一個元素并返回它,或者如果我們已經到達集合的末尾則返回None。它的實現大致如下:

traitIterator{
typeItem;

fnnext(&mutself)->Option;
}
然后,我們可以創建一種方法來遍歷Todos列表字段的元素,編寫一個自定義的next()函數。這樣做的邏輯很簡單——我們可以在偽代碼中這樣做:
functionnext(){
ifindex

在上面的邏輯中,我們檢查元素的索引并返回它,前提是它的索引小于列表長度。但我們有個問題。在哪里存儲索引?

存儲狀態

這就是迭代器和可迭代對象之間的區別。翻譯上面的偽代碼,可以像這樣在Todos中實現next()函數,從Iterator trait實現一個方法:

impl<'a>IteratorforTodos{
typeItem=&'aTodo;
fnnext(&mutself)->Option{
ifself.index
但這需要我們改變Todos的結構:我們需要在其中添加一個索引(index)字段,以便每次調用next()時使用——也就是說,每次通過迭代器迭代它的元素時使用。
pubstructTodos{
publist:Vec,
index:usize,
}
在這個邏輯中,我們將修改構造函數,以便始終創建索引為0的結構體。
pubfnnew(list:Vec)->Self{
Todos{list,index:0}
}

然而,這種方法感覺不太對……

在結構體中存儲索引字段并不理想,索引用于在迭代器中存儲當前狀態,因此它應該是迭代器的一部分,而不是結構體的一部分。這就是為什么我們要創建一個迭代器類型——它將存儲索引屬性——并為該類型實現iterator特性的原因。

TodoIterator

首先,我們需要創建一個迭代器類型:

structTodosIterator<'a>{
todos:&'aTodos,
index:usize,
}

注意這里的生命周期注釋,TodosIterator有一個todos字段,它引用了一個Todos。當我們處理引用時,我們需要確保這個字段指向有效的東西——這里就需要生命周期參數

TodosIterator結構體在此的生命周期是'a,基本上,我們使用這個符號來指定迭代器的todos字段需要具有相同的生命周期。這樣,我們就可以確保它不能引用已被刪除的Todos結構體。

接下來我們來實現TodosIterator的迭代器:

impl<'a>IteratorforTodosIterator<'a>{
typeItem=&'aTodo;

fnnext(&mutself)->Option{
ifself.index
現在我們已經創建了TodoIterator結構體,并為該結構體實現了Iterator特性,我們如何使用它來迭代Todos呢?答案在于Todos結構體的iter()方法,該方法接受Todos的一個引用,并使用它來創建一個迭代器,我們可以使用它來進行迭代!
implTodos{
pubfniter(&self)->TodosIterator{
TodosIterator{
todos:self,
index:0,
}
}
}

//Nowwecaniterate:
fortodointodos.iter(){
println!("{}",todo);//eachtodoisa&Todo,andisimmutable
}

IntoIterator

IntoIterator與Iterator特性有點不同,它有一個單一方法into_iter()返回覆蓋數據的迭代器。這使得所有實現IntoIterator的類型都可以轉換為Iterator。

讓我們來理解它的實現:

pubtraitIntoIterator{
typeItem;
typeIntoIter:Iterator;

fninto_iter(self)->Self::IntoIter;
}

這里有一些關鍵的點:

1,Item類型參數是迭代器將生成的元素的類型。

2,IntoIter類型參數是into_iter方法返回的迭代器的類型。這個類型必須實現Iterator trait,并且它的Item的類型必須與IntoIterator的Item的類型相同。

3,into_iter方法接受self作為參數,這意味著它使用原始對象并返回一個遍歷其元素的迭代器。

怎么實現呢?你可能認為我們可以重用TodosIterator——然而,我們不能這樣做,因為它需要&Todos,而且這里需要獲得迭代對象的所有權。那么讓我們創建另一個迭代器來完成它:

pubstructTodosIntoIterator{
todos:Todos
}

TodosIntoIterator和TodosIterator的區別在于,這里我們沒有使用引用,而是獲取所有權并返回每個元素本身——這就是為什么我們不再需要生命周期注釋了。而且也沒有索引來保存狀態,我們很快就會看到原因。

遵循IntoIterator trait的定義,我們可以為Todos實現它:

implIntoIteratorforTodos{
typeItem=Todo;
typeIntoIter=TodosIntoIterator;

fninto_iter(self)->TodosIntoIterator{
TodosIntoIterator{todos:self}
}
}
然而,在此之前,我們需要實現TodosIntoIterator的Iterator(還記得類型參數嗎?)來描述我們將如何迭代它。
implIteratorforTodosIntoIterator{
typeItem=Todo;

fnnext(&mutself)->Option{
ifself.todos.list.len()==0{
returnNone;
}
letresult=self.todos.list.remove(0);
Some(result)
}
}

這個實現與我們為TodosIterator所做的略有不同,我們利用了Rust中存在的用于Vecs的remove()方法。該方法移除位置n處的元素并將其返回給我們,并給出其所有權(這對于返回Todo而不是&Todo是必要的)。由于這個方法的工作方式,我們總是可以使用“0”來返回第一個元素,而不是存儲一個狀態并按順序增加它。

現在,我們完成了!這兩種實現使我們能夠以兩種不同的方式迭代Todos:

1,引用的方式(&Todos)

fortodointodo_list.iter(){
println!("{}",todo);//todoisa&Todo
}
2,獲取所有權的方式
fortodointodo_list{
println!("{}",todo);//todoisaTodo
}

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編程語言
    +關注

    關注

    10

    文章

    1942

    瀏覽量

    34707
  • 迭代器
    +關注

    關注

    0

    文章

    43

    瀏覽量

    4307
  • Rust
    +關注

    關注

    1

    文章

    228

    瀏覽量

    6601

原文標題:在Rust中實現Iterator和IntoIterator特征

文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何使用Rust語言和paho-mqtt模塊實現MQTT協議

    模塊實現MQTT協議,并重點介紹LWT特征Rust是一種系統級編程語言,它的主要特點是安全、高效、并發。Rust編譯器會在編譯時進行內存安全檢查,避免了很多常見的內存安全問題,如空
    的頭像 發表于 09-19 14:41 ?1972次閱讀

    基于Rust語言Hash特征的基礎用法和進階用法

    Rust語言是一種系統級編程語言,具有高性能、安全、并發等特點,是近年來備受關注的新興編程語言。Rust語言中,Hash是一種常用的數據結構,用于存儲鍵值對。Rust語言提供了一系列
    的頭像 發表于 09-19 16:02 ?1444次閱讀

    如何在Rust讀寫文件

    見的內存安全問題和數據競爭問題。 Rust,讀寫文件是一項非常常見的任務。本教程將介紹如何在Rust讀寫文件,包括基礎用法和進階用法。
    的頭像 發表于 09-20 10:57 ?2035次閱讀

    Rust 語言中的 RwLock內部實現原理

    中的 RwLock 的內部實現原理、常用接口的使用技巧和最佳實踐。 RwLock 的內部實現原理 基本概念 RwLock 是一種讀寫分離的鎖,允許多個線程同時讀取共享數據,但只允許一個線程寫入數據。通過這種方式,可以避免讀寫操作之間的競爭,從而提高并發性能。
    的頭像 發表于 09-20 11:23 ?866次閱讀

    踩坑rust的partial copy導致metrics丟失

    metrics 丟失。實現,我們設計了一個 rust 的 struct MonitoredStateStoreIterStats 去收集 LSM
    的頭像 發表于 01-03 10:02 ?422次閱讀

    只會用Python?教你樹莓派上開始使用Rust

    如果您對編程感興趣,那么您可能聽說過Rust。該語言由Mozilla設計,受到開發人員的廣泛喜愛,并繼續奉獻者成長。Raspberry Pi是小型計算機的瑞士軍刀,非常適合學習代碼。我們將兩者
    發表于 05-20 08:00

    怎樣去使用Rust進行嵌入式編程呢

    使用Rust進行嵌入式編程Use Rust for embedded development篇首語:Rust的高性能、可靠性和生產力使其適合于嵌入式系統。在過去的幾年里,Rust
    發表于 12-22 07:20

    RUST嵌入式開發的應用是什么

    Rust是一種編程語言,它使用戶能夠構建可靠、高效的軟件,尤其是用于嵌入式開發的軟件。它的特點是:高性能:Rust具有驚人的速度和高內存利用率。可靠性:在編譯過程可以消除內存錯誤。生產效率:優秀
    發表于 12-24 08:34

    Rust代碼中加載靜態庫時,出現錯誤 ` rust-lld: error: undefined symbol: malloc `怎么解決?

    我正在 MCUXpresso IDE 創建一個靜態庫。我正在使用 redlib 我的代碼中導入 ` [i]stdlib.h`。它成功地構建了一個靜態庫。但是,靜態庫未定義一些標準庫函數,例如
    發表于 06-09 08:44

    Java的iterator和foreach遍歷集合源代碼

    Java的iterator和foreach遍歷集合源代碼
    發表于 03-17 09:16 ?9次下載
    Java的<b class='flag-5'>iterator</b>和foreach遍歷集合源代碼

    Linux內核整合對 Rust 的支持

    Linux Plumbers Conference 2022 大會上舉行了一個 Rust 相關的小型會議,該會議討論的大方向大致為:正在進行的使 Rust 成為一種合適的系統編程語言的工作,以及主線 Linux 內核
    的頭像 發表于 09-19 11:06 ?1171次閱讀

    Rust虛幻引擎5的使用

    前段時間,研究了一套 Rust 接入 Maya Plugin 的玩法,主要原理還是使用 C ABI 去交互。那我想著 UE 是使用 C++ 寫的,肯定也可以使用 C ABI 去交互,如果可以的話 UE 中就可以使用 Rust
    的頭像 發表于 12-21 11:05 ?6097次閱讀

    Rust的錯誤處理方法

    Rust 沒有提供類似于 Java、C++ 的 Exception 機制,而是使用 Result 枚舉的方式來實現
    的頭像 發表于 02-20 09:37 ?945次閱讀

    rust語言基礎學習: rust的錯誤處理

    錯誤是軟件不可避免的,所以 Rust 有一些處理出錯情況的特性。許多情況下,Rust 要求你承認錯誤的可能性,并在你的代碼編譯前采取一些行動。
    的頭像 發表于 05-22 16:28 ?2104次閱讀

    RustPin/Unpin詳解

    對我來說,其中之一就是Rust Pin/Unpin 。
    的頭像 發表于 07-20 11:00 ?882次閱讀
    主站蜘蛛池模板: 野花高清在线观看免费3中文| 欧美丰满熟妇无码XOXOXO| 97人妻AV天天澡夜夜爽| 欧美日韩中文国产一区发布| 处88XXX| 亚洲国产综合另类视频| 旧里番ovaの催○セイ活指导| bt成人社区| 小sao货ji巴cao死你视频| 久久偷拍国2017| 亚洲片在线观看| 69国产精品人妻无码免费| 成人18视频在线观看| 国产又黄又粗又爽又色的视频软件 | 91久久夜色精品| 在线观看日韩一区| 边做边爱播放3免费观看| 八妻子秋霞理在线播放| 国产欧美在线亚洲一区刘亦菲| 久久这里只有精品视频9| 男人插曲女人身体视频| 国产69精品久久久久人妻刘玥 | 亚洲网站视频在线观看| ewp系列虐杀在线视频| bbwvideos欧美老妇| 国产区精品综合在线| 国产亚洲tv在线观看| 人妻久久久精品99系列AV| 亚洲精品午夜久久久伊人| 国产精品99久久久久久宅男AV| 免费在线观看的毛片| 亚洲一区在线观看视频| 97精品国产高清在线看入口| 国产精品女上位在线观看| 亚洲精品成人无码A片在线| 成年视频国产免费观看| 被室友C哭调教双性| 92看看福利午夜影院| 欲乱艳荡少寡妇全文免费| 羞羞答答影院在线| 色欲AV精品一区二区入口|