Rust for循環(huán)語法糖背后的API場(chǎng)景分析
Rust中for循環(huán)實(shí)質(zhì)上是一個(gè)語法糖,in后面的對(duì)象要求是一個(gè)迭代器,for循環(huán)就是對(duì)這個(gè)迭代器循環(huán)調(diào)用next,而in前面的名稱就是每一次迭代后返回的結(jié)果,如果next返回Option::None則退出循環(huán)。了解這一點(diǎn)后我們可以自己編寫自己的迭代器類型,然后使用for循環(huán)進(jìn)行迭代。
rust有三種for循環(huán),分別用于不同的場(chǎng)景。
1.拿走所有權(quán)的for循環(huán)
形式如:for item in collection
(集合或容器類型)會(huì)拿走collection的所有權(quán)(ownership)
。
fn main() { let collection: Vec<i32> = vec![1, 2, 4, 6, 9]; // 注意這兒的item類型是i32 for item in collection { println!("item:{}", item); } // for循環(huán)之后,不能再使用collection,因?yàn)閏ollection的所有權(quán)已經(jīng)被拿走,且在for循環(huán)后collection已經(jīng)被drop掉了 // println!("collection:{:?}", collection); }
因?yàn)閞ust編譯器會(huì)將for item in collection
替換成for item in IntoIterator::into_iter(collection)
:
fn main() { let collection: Vec<i32> = vec![1, 2, 4, 6, 9]; // rust中的into_開頭的方法一般情況下都會(huì)拿走參數(shù)的所有權(quán) let iter = IntoIterator::into_iter(collection); // 從這兒開始,collection已經(jīng)不能再被使用,因?yàn)閏ollection的所有權(quán)被轉(zhuǎn)移到into_iter方法中,當(dāng)方法執(zhí)行完,collection就被drop掉了 // println!("collection:{:?}", collection); // 如果這兒使用collection就會(huì)編譯報(bào)錯(cuò) for item in iter{ println!("item:{}", item); } }
正如Rust官網(wǎng)https://doc.rust-lang.org/std/iter/trait.IntoIterator.html上說的:One benefit of implementing IntoIterator
is that your type will work with Rust’s for
loop syntax.,即實(shí)現(xiàn)IntoIterator trait能夠讓你自定義類型在for循環(huán)中使用。
Vec正是實(shí)現(xiàn)了IntoIterator,所以才可以在for循環(huán)中使用的:
2.只讀for循環(huán)
形式如:for item in &collection
,不會(huì)拿走collection的所有權(quán),只會(huì)獲取它的不可變引用:
fn main() { let collection: Vec<i32> = vec![1, 2, 4, 6, 9]; // 注意這兒item的類型是&i32,即它是對(duì)collection中元素的不可變引用 for item in &collection { println!("item:{}", item); } println!("collection after for loop:{:?}", collection); }
因?yàn)閞ust會(huì)將for item in &collection
替換成for item in collection.iter()
:
fn main() { let collection: Vec<i32> = vec![1, 2, 4, 6, 9]; // 注意這兒item的類型是&i32,即它是對(duì)collection中元素的不可變引用 for item in collection.iter() { // 等價(jià)于for item in (&collection).iter() { println!("item:{}", item); } println!("collection after for loop:{:?}", collection); }
迭代完集合中的元素后,集合還可以繼續(xù)使用。
3.讀寫for循環(huán)
形式如:for item in &mut collection
,不會(huì)拿走collection的所有權(quán),只會(huì)獲取它的可變引用:
fn main() { // 注意,為了修改collection中的元素,collection本身必須聲明為mut let mut collection: Vec<i32> = vec![1, 2, 4, 6, 9]; // 注意這兒item的類型是&mut i32,即它是對(duì)collection中元素的可變引用 for item in &mut collection { // 通過*對(duì)可變引用進(jìn)行解引用,從而可以修改引用指向的值 *item = *item +1; println!("item:{}", item); } println!("collection after for loop:{:?}", collection); }
上面的程序運(yùn)行輸出:
item:2
item:3
item:5
item:7
item:10
collection after for loop:[2, 3, 5, 7, 10]
實(shí)現(xiàn)了對(duì)集合元素的修改。
因?yàn)閞ust會(huì)將for item in &mut collection
替換成for item in collection.iter_mut()
:
fn main() { // 注意,為了修改collection中的元素,collection本身必須聲明為mut let mut collection: Vec<i32> = vec![1, 2, 4, 6, 9]; // 注意這兒item的類型是&mut i32,即它是對(duì)collection中元素的可變引用 for item in collection.iter_mut() { // 等價(jià)于for item in (&mut collection).iter_mut() { // 通過*對(duì)可變引用進(jìn)行解引用,從而可以修改引用指向的值 *item = *item +1; println!("item:{}", item); } println!("collection after for loop:{:?}", collection); }
參考資料:
1.《Rust實(shí)戰(zhàn)》(Rust In Action)
到此這篇關(guān)于Rust for循環(huán)語法糖背后的API的文章就介紹到這了,更多相關(guān)Rust for循環(huán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust?搭建一個(gè)小程序運(yùn)行環(huán)境的方法詳解
rust是一門比較新的編程語言,2015年5月15日,Rust編程語言核心團(tuán)隊(duì)正式宣布發(fā)布Rust?1.0版本,本文給大家介紹Rust?搭建一個(gè)小程序運(yùn)行環(huán)境,以iOS?為例介紹開發(fā)環(huán)境的準(zhǔn)備,感興趣的朋友跟隨小編一起看看吧2022-05-05Rust重載運(yùn)算符之復(fù)數(shù)四則運(yùn)算的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Rust如何實(shí)現(xiàn)復(fù)數(shù)以及復(fù)數(shù)的四則運(yùn)算,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-08-08Rust生成隨機(jī)數(shù)的項(xiàng)目實(shí)踐
Rust標(biāo)準(zhǔn)庫(kù)中并沒有隨機(jī)數(shù)生成器,常見的解決方案是使用rand包,本文主要介紹了Rust生成隨機(jī)數(shù)的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Rust使用kind進(jìn)行異常處理(錯(cuò)誤的分類與傳遞)
Rust?有一套獨(dú)特的處理異常情況的機(jī)制,它并不像其它語言中的?try?機(jī)制那樣簡(jiǎn)單,這篇文章主要介紹了Rust指南錯(cuò)誤的分類與傳遞以及使用kind進(jìn)行異常處理,需要的朋友可以參考下2022-09-09