欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在Rust中實(shí)現(xiàn)Iterator和IntoIterator特征

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

迭代器是一種強(qiáng)大的工具,它允許對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行有效的迭代,并且在許多編程語(yǔ)言中都實(shí)現(xiàn)了迭代器。然而,Rust獨(dú)特的所有權(quán)系統(tǒng)在如何實(shí)現(xiàn)和使用迭代器方面產(chǎn)生了有趣的差異。在本文中,我們將通過(guò)創(chuàng)建和實(shí)現(xiàn)最常用的迭代器特征——iterator和IntoIterator,來(lái)探索這些差異。

假設(shè)你有一個(gè)這樣的結(jié)構(gòu)體:

pubstructTodos{
publist:Vec,
}

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

Iterator

在Rust中,與Python等語(yǔ)言類(lèi)似,迭代器是惰性的。這意味著除非對(duì)它們進(jìn)行迭代(也就是消耗它們),否則它們是無(wú)效的。

letnumbers=vec![1,2,3];
letnumbers_iter=numbers.iter();
上面的代碼創(chuàng)建了一個(gè)迭代器——但沒(méi)有對(duì)它做任何操作。要使用迭代器,我們應(yīng)該創(chuàng)建一個(gè)for循環(huán),如下所示:
letnumbers=vec![1,2,3];
letnumbers_iter=numbers.iter();

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

還有其他方法可以用來(lái)創(chuàng)建迭代器。例如,每次在Rust中使用map()時(shí),我們都在創(chuàng)建一個(gè)迭代器。

迭代器 vs 可迭代對(duì)象

如前所述,vector是一個(gè)可迭代對(duì)象。這意味著我們可以對(duì)它們進(jìn)行迭代;但更準(zhǔn)確地說(shuō),這意味著我們可以使用Vec來(lái)創(chuàng)建Iterator。例如,Vec可以生成一個(gè)迭代器,但它本身不是迭代器。

創(chuàng)建迭代器

讓我們回到Todos結(jié)構(gòu)體看看我們?nèi)绾蝿?chuàng)建一種方法來(lái)迭代它的元素。Todos有一個(gè)字段列表,它是一個(gè)Vec。

在Rust中,Iterator是一個(gè)trait,其中包含一些方法,例如next(),它負(fù)責(zé)獲取集合的下一個(gè)元素并返回它,或者如果我們已經(jīng)到達(dá)集合的末尾則返回None。它的實(shí)現(xiàn)大致如下:

traitIterator{
typeItem;

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

在上面的邏輯中,我們檢查元素的索引并返回它,前提是它的索引小于列表長(zhǎng)度。但我們有個(gè)問(wèn)題。在哪里存儲(chǔ)索引?

存儲(chǔ)狀態(tài)

這就是迭代器和可迭代對(duì)象之間的區(qū)別。翻譯上面的偽代碼,可以像這樣在Todos中實(shí)現(xiàn)next()函數(shù),從Iterator trait實(shí)現(xiàn)一個(gè)方法:

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

然而,這種方法感覺(jué)不太對(duì)……

在結(jié)構(gòu)體中存儲(chǔ)索引字段并不理想,索引用于在迭代器中存儲(chǔ)當(dāng)前狀態(tài),因此它應(yīng)該是迭代器的一部分,而不是結(jié)構(gòu)體的一部分。這就是為什么我們要?jiǎng)?chuàng)建一個(gè)迭代器類(lèi)型——它將存儲(chǔ)索引屬性——并為該類(lèi)型實(shí)現(xiàn)iterator特性的原因。

TodoIterator

首先,我們需要?jiǎng)?chuàng)建一個(gè)迭代器類(lèi)型:

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

注意這里的生命周期注釋?zhuān)琓odosIterator有一個(gè)todos字段,它引用了一個(gè)Todos。當(dāng)我們處理引用時(shí),我們需要確保這個(gè)字段指向有效的東西——這里就需要生命周期參數(shù)。

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

接下來(lái)我們來(lái)實(shí)現(xiàn)TodosIterator的迭代器:

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

fnnext(&mutself)->Option{
ifself.index
現(xiàn)在我們已經(jīng)創(chuàng)建了TodoIterator結(jié)構(gòu)體,并為該結(jié)構(gòu)體實(shí)現(xiàn)了Iterator特性,我們?nèi)绾问褂盟鼇?lái)迭代Todos呢?答案在于Todos結(jié)構(gòu)體的iter()方法,該方法接受Todos的一個(gè)引用,并使用它來(lái)創(chuàng)建一個(gè)迭代器,我們可以使用它來(lái)進(jìn)行迭代!
implTodos{
pubfniter(&self)->TodosIterator{
TodosIterator{
todos:self,
index:0,
}
}
}

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

IntoIterator

IntoIterator與Iterator特性有點(diǎn)不同,它有一個(gè)單一方法into_iter()返回覆蓋數(shù)據(jù)的迭代器。這使得所有實(shí)現(xiàn)IntoIterator的類(lèi)型都可以轉(zhuǎn)換為Iterator。

讓我們來(lái)理解它的實(shí)現(xiàn):

pubtraitIntoIterator{
typeItem;
typeIntoIter:Iterator;

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

這里有一些關(guān)鍵的點(diǎn):

1,Item類(lèi)型參數(shù)是迭代器將生成的元素的類(lèi)型。

2,IntoIter類(lèi)型參數(shù)是into_iter方法返回的迭代器的類(lèi)型。這個(gè)類(lèi)型必須實(shí)現(xiàn)Iterator trait,并且它的Item的類(lèi)型必須與IntoIterator的Item的類(lèi)型相同。

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

怎么實(shí)現(xiàn)呢?你可能認(rèn)為我們可以重用TodosIterator——然而,我們不能這樣做,因?yàn)樗枰?Todos,而且這里需要獲得迭代對(duì)象的所有權(quán)。那么讓我們創(chuàng)建另一個(gè)迭代器來(lái)完成它:

pubstructTodosIntoIterator{
todos:Todos
}

TodosIntoIterator和TodosIterator的區(qū)別在于,這里我們沒(méi)有使用引用,而是獲取所有權(quán)并返回每個(gè)元素本身——這就是為什么我們不再需要生命周期注釋了。而且也沒(méi)有索引來(lái)保存狀態(tài),我們很快就會(huì)看到原因。

遵循IntoIterator trait的定義,我們可以為T(mén)odos實(shí)現(xiàn)它:

implIntoIteratorforTodos{
typeItem=Todo;
typeIntoIter=TodosIntoIterator;

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

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

這個(gè)實(shí)現(xiàn)與我們?yōu)門(mén)odosIterator所做的略有不同,我們利用了Rust中存在的用于Vecs的remove()方法。該方法移除位置n處的元素并將其返回給我們,并給出其所有權(quán)(這對(duì)于返回Todo而不是&Todo是必要的)。由于這個(gè)方法的工作方式,我們總是可以使用“0”來(lái)返回第一個(gè)元素,而不是存儲(chǔ)一個(gè)狀態(tài)并按順序增加它。

現(xiàn)在,我們完成了!這兩種實(shí)現(xiàn)使我們能夠以兩種不同的方式迭代Todos:

1,引用的方式(&Todos)

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

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編程語(yǔ)言
    +關(guān)注

    關(guān)注

    10

    文章

    1951

    瀏覽量

    35018
  • 迭代器
    +關(guān)注

    關(guān)注

    0

    文章

    44

    瀏覽量

    4350
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    230

    瀏覽量

    6674

原文標(biāo)題:在Rust中實(shí)現(xiàn)Iterator和IntoIterator特征

文章出處:【微信號(hào):Rust語(yǔ)言中文社區(qū),微信公眾號(hào):Rust語(yǔ)言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何使用Rust語(yǔ)言和paho-mqtt模塊實(shí)現(xiàn)MQTT協(xié)議

    模塊實(shí)現(xiàn)MQTT協(xié)議,并重點(diǎn)介紹LWT特征。 Rust是一種系統(tǒng)級(jí)編程語(yǔ)言,它的主要特點(diǎn)是安全、高效、并發(fā)。Rust編譯器會(huì)在編譯時(shí)進(jìn)行內(nèi)存安全檢查,避免了很多常見(jiàn)的內(nèi)存安全問(wèn)題,如空
    的頭像 發(fā)表于 09-19 14:41 ?2045次閱讀

    基于Rust語(yǔ)言Hash特征的基礎(chǔ)用法和進(jìn)階用法

    Rust語(yǔ)言是一種系統(tǒng)級(jí)編程語(yǔ)言,具有高性能、安全、并發(fā)等特點(diǎn),是近年來(lái)備受關(guān)注的新興編程語(yǔ)言。Rust語(yǔ)言中,Hash是一種常用的數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)鍵值對(duì)。Rust語(yǔ)言提供了一系列
    的頭像 發(fā)表于 09-19 16:02 ?1548次閱讀

    如何在Rust讀寫(xiě)文件

    見(jiàn)的內(nèi)存安全問(wèn)題和數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題。 Rust,讀寫(xiě)文件是一項(xiàng)非常常見(jiàn)的任務(wù)。本教程將介紹如何在Rust讀寫(xiě)文件,包括基礎(chǔ)用法和進(jìn)階用法。
    的頭像 發(fā)表于 09-20 10:57 ?2141次閱讀

    Rust 語(yǔ)言中的 RwLock內(nèi)部實(shí)現(xiàn)原理

    中的 RwLock 的內(nèi)部實(shí)現(xiàn)原理、常用接口的使用技巧和最佳實(shí)踐。 RwLock 的內(nèi)部實(shí)現(xiàn)原理 基本概念 RwLock 是一種讀寫(xiě)分離的鎖,允許多個(gè)線程同時(shí)讀取共享數(shù)據(jù),但只允許一個(gè)線程寫(xiě)入數(shù)據(jù)。通過(guò)這種方式,可以避免讀寫(xiě)操作之間的競(jìng)爭(zhēng),從而提高并發(fā)性能。
    的頭像 發(fā)表于 09-20 11:23 ?929次閱讀

    踩坑rust的partial copy導(dǎo)致metrics丟失

    metrics 丟失。實(shí)現(xiàn),我們?cè)O(shè)計(jì)了一個(gè) rust 的 struct MonitoredStateStoreIterStats 去收集 LSM
    的頭像 發(fā)表于 01-03 10:02 ?462次閱讀

    只會(huì)用Python?教你樹(shù)莓派上開(kāi)始使用Rust

    如果您對(duì)編程感興趣,那么您可能聽(tīng)說(shuō)過(guò)Rust。該語(yǔ)言由Mozilla設(shè)計(jì),受到開(kāi)發(fā)人員的廣泛喜愛(ài),并繼續(xù)奉獻(xiàn)者成長(zhǎng)。Raspberry Pi是小型計(jì)算機(jī)的瑞士軍刀,非常適合學(xué)習(xí)代碼。我們將兩者
    發(fā)表于 05-20 08:00

    怎樣去使用Rust進(jìn)行嵌入式編程呢

    使用Rust進(jìn)行嵌入式編程Use Rust for embedded development篇首語(yǔ):Rust的高性能、可靠性和生產(chǎn)力使其適合于嵌入式系統(tǒng)。在過(guò)去的幾年里,Rust
    發(fā)表于 12-22 07:20

    RUST嵌入式開(kāi)發(fā)的應(yīng)用是什么

    Rust是一種編程語(yǔ)言,它使用戶能夠構(gòu)建可靠、高效的軟件,尤其是用于嵌入式開(kāi)發(fā)的軟件。它的特點(diǎn)是:高性能:Rust具有驚人的速度和高內(nèi)存利用率??煽啃裕涸诰幾g過(guò)程可以消除內(nèi)存錯(cuò)誤。生產(chǎn)效率:優(yōu)秀
    發(fā)表于 12-24 08:34

    Rust代碼中加載靜態(tài)庫(kù)時(shí),出現(xiàn)錯(cuò)誤 ` rust-lld: error: undefined symbol: malloc `怎么解決?

    我正在 MCUXpresso IDE 創(chuàng)建一個(gè)靜態(tài)庫(kù)。我正在使用 redlib 我的代碼中導(dǎo)入 ` [i]stdlib.h`。它成功地構(gòu)建了一個(gè)靜態(tài)庫(kù)。但是,靜態(tài)庫(kù)未定義一些標(biāo)準(zhǔn)庫(kù)函數(shù),例如
    發(fā)表于 06-09 08:44

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

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

    Linux內(nèi)核整合對(duì) Rust 的支持

    Linux Plumbers Conference 2022 大會(huì)上舉行了一個(gè) Rust 相關(guān)的小型會(huì)議,該會(huì)議討論的大方向大致為:正在進(jìn)行的使 Rust 成為一種合適的系統(tǒng)編程語(yǔ)言的工作,以及主線 Linux 內(nèi)核
    的頭像 發(fā)表于 09-19 11:06 ?1212次閱讀

    Rust虛幻引擎5的使用

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

    Rust的錯(cuò)誤處理方法

    Rust 沒(méi)有提供類(lèi)似于 Java、C++ 的 Exception 機(jī)制,而是使用 Result 枚舉的方式來(lái)實(shí)現(xiàn)。
    的頭像 發(fā)表于 02-20 09:37 ?1010次閱讀

    rust語(yǔ)言基礎(chǔ)學(xué)習(xí): rust的錯(cuò)誤處理

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

    RustPin/Unpin詳解

    對(duì)我來(lái)說(shuō),其中之一就是Rust Pin/Unpin 。
    的頭像 發(fā)表于 07-20 11:00 ?1011次閱讀