<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在Rust語言中,迭代器(Iterator)是一種極為重要的資料型別,它們用於遍歷集合中的元素。Rust中的大多數集合型別都可轉換為一個迭代器,使它們可以進行遍歷,這包括陣列、向量、雜湊表等。
使用迭代器可以讓程式碼更加簡潔優雅,並且可以支援一些強大的操作,例如過濾、對映和摺疊等。
在本文中,我們將探討Rust語言中的迭代器的相關知識,並且以我們的老朋友Animal為例,提供相關的範例程式碼。
熟悉Java的Stream和Lambda的同學,學習本章節時,會格外的感覺“親切”。
在Rust中,迭代器是一個實現了Iterator trait的型別。該trait定義了一組行為,用於支援遍歷集合中的元素。通過實現Iterator trait,型別可以被轉換為一個迭代器,從而支援Iterate的操作。
Iterator trait 定義了迭代器的核心行為,它包含了next方法和一些其他方法。next方法返回集合中下一個元素的Option值,直到集合中所有的元素都被遍歷完畢,返回None。
除了next方法之外,Iterator trait 還定義了其他許多有用的方法,比如map、filter等,這些方法可以對迭代器中的元素進行操作和轉換。
pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; // 多種內建實現方法, skip, map, reduce, collect // 和Java中的Stream內建方法非常類似. }
接下來我們探討實現一個Animal迭代器,Animal實現Iterator trait,使其可以通過迭代器遍歷Animal的各個屬性。 以下是Animal型別的定義:
#[derive(Debug)] struct Animal { name: String, age: u32, kind: String, i:i32, }
我們可以在Animal上實現Iterator trait,使其可以通過for迴圈進行迭代。
impl Iterator for Animal { type Item = String; fn next(&mut self) -> Option<Self::Item> { let next_attribute = match self.i { 0 => Some(self.name.clone()), 1 => Some(self.age.to_string()), 2 => Some(self.kind.clone()), _ => None, }; self.i += 1; next_attribute } }
此時,我們已經將我們的型別轉換為迭代器,我們就可以在它上面呼叫各種Iterator trait 的方法。例如,我們可以使用for迴圈遍歷Animal物件的每一個屬性:
#[derive(Debug)] struct Animal { name: String, age: u32, kind: String, i:i32, } impl Iterator for Animal { type Item = String; fn next(&mut self) -> Option<Self::Item> { let next_attribute = match self.i { 0 => Some(self.name.clone()), 1 => Some(self.age.to_string()), 2 => Some(self.kind.clone()), _ => None, }; self.i += 1; next_attribute } } fn main() { let mut animal = Animal { name: "Tom".to_string(), age : 15, kind: "cat".to_string(), i : 0 }; println!("Name: {}", animal.next().unwrap()); println!("Age: {}", animal.next().unwrap()); println!("Kind: {}", animal.next().unwrap()); } // 輸出結果: // Name: Tom // Age: 15 // Kind: cat
在上述程式碼中,我們定義了一個Animal型別的Iterator,並定義了一個名為i的內部狀態變數。該變數用於追蹤遍歷的進度,並決定下一個迭代器值的內容。最終成功列印了animal的全部資訊。
下面繼續我們的學習,定一個Animal向量並遍歷列印每一個Animal的所有屬性:
fn print_all_attributes(animals: Vec<Animal>) { for mut animal in animals { println!("Name: {}", animal.next().unwrap()); println!("Age: {}", animal.next().unwrap()); println!("Kind: {}", animal.next().unwrap()); } } fn main() { let animals = vec![Animal { name: "Tom".to_string(), age : 15, kind: "cat".to_string(), i : 0 }]; print_all_attributes(animals); } // 輸出結果: // Name: Tom // Age: 15 // Kind: cat
在上述程式碼中,我們使用for迴圈來遍歷所有的Animal物件,並逐一列印它們的屬性。
map方法是Iterator trait 中非常重要的一個方法,它可以讓我們對迭代器中的每一個元素進行轉換操作,並返回新的迭代器。例如:
fn main() { let animals = vec![Animal { name: "Tom".to_string(), age : 15, kind: "cat".to_string(), i : 0 }, Animal { name: "Jerry".to_string(), age : 7, kind: "mouse".to_string(), i : 0 }]; let list: Vec<String> = animals .into_iter() .map(|ani| ani.name.clone()) .collect(); println!("{:?}", list) } // 輸出 ["Tom", "Jerry"]
上述程式碼中,我們定義了一個包含2個的向量animals,並使用iter方法將其轉換為一個迭代器。然後,我們使用map方法對這個迭代器中的Animal的name操作,返回一個新的迭代器,並使用collect方法將其轉換為向量list。
假設我們現在想尋找年齡大於等於3歲的動物,我們可以使用filter方法來實現。
fn main() { let animals = vec![Animal { name: "Tom".to_string(), age : 15, kind: "cat".to_string(), i : 0 }]; let filtered_animals: Vec<Animal> = animals .into_iter() .filter(|animal| animal.age >= 3) .collect(); println!("{:?}", filtered_animals) } // 輸出結果: // [Animal { name: "Tom", age: 15, kind: "cat", i: 0 }]
在上述程式碼中,我們使用into_iter方法將Animal向量轉換為迭代器,並使用filter方法過濾其中年齡大於等於3歲的動物,最終返回一個新的Animal向量。
enumerate方法會將一個迭代器中的元素和它們的索引配對,並返回一個新的迭代器。例如:
fn main() { let animals = vec![Animal { name: "Tom".to_string(), age : 15, kind: "cat".to_string(), i : 0 }, Animal { name: "Jerry".to_string(), age : 7, kind: "mouse".to_string(), i : 0 }]; for (i, animal) in animals.iter().enumerate() { println!("{}: {:?}", i, animal); } } // 輸出: // 0: Animal { name: "Tom", age: 15, kind: "cat", i: 0 } // 1: Animal { name: "Jerry", age: 7, kind: "mouse", i: 0 }
上述程式碼中,我們定義了一個包含2個Animal的向量animals,並使用iter方法將其轉換為一個迭代器。然後,我們使用enumerate方法將每Animal與其索引配對,並在for迴圈中列印出來。
flat_map方法是Iterator trait 中比較少見的方法之一,它可以用於將巢狀的迭代器展開為單個迭代器。例如:
#[derive(Debug, Clone)] struct Animal { name: String, age: u32, kind: String, i: i32, } fn main() { let cat = Animal { name: "Tom".to_string(), age: 15, kind: "cat".to_string(), i: 0, }; let mouse = Animal { name: "Jerry".to_string(), age: 7, kind: "mouse".to_string(), i: 0, }; let animals = vec![vec![cat], vec![mouse]]; let list: Vec<Animal> = animals.iter().flat_map(|x| x.iter().cloned()).collect(); println!("{:?}", list) } // 輸出 [Animal { name: "Tom", age: 15, kind: "cat", i: 0 }, Animal { name: "Jerry", age: 7, kind: "mouse", i: 0 }]
上述程式碼中,我們定義了一個二維向量animals,並使用iter方法將它轉換為迭代器。然後,我們使用flat_map方法將它展開為一個一維的迭代器,並使用collect方法將其轉換為向量list。
如果我們需要同時遍歷兩個向量,我們可以使用zip方法進行配對。
fn main() { let names = vec!["Tom", "Jerry", "Bob"]; let ages = vec![3, 4, 5]; for (name, age) in names.iter().zip(ages.iter()) { println!("{} is {} years old.", name, age); } } // 輸出結果: // Tom is 3 years old. // Jerry is 4 years old. // Bob is 5 years old.
上述程式碼中,我們使用iter方法將names和ages向量轉換為迭代器,並使用zip方法對它們進行配對。對於每一對元素,我們呼叫println!函數並列印它們。
fold方法在Rust中也十分重要,它可以接受一個初始值和一個閉包,遍歷迭代器中的每一個元素,並將它們合併成單個值。例如:
fn main() { let cat = Animal { name: "Tom".to_string(), age: 15, kind: "cat".to_string(), i: 0, }; let mouse = Animal { name: "Jerry".to_string(), age: 7, kind: "mouse".to_string(), i: 0, }; let animals = vec![cat, mouse]; let sum = animals.iter().fold(0, |t, ani| t + ani.age ); println!("{}", sum) } // 輸出 22
上述程式碼中,我們定義了一個包含2個Animal的向量animals,並使用iter方法將其轉換為一個迭代器。然後,我們使用fold方法對這個迭代器中的age進行累加,並返回結果sum。
迭代器是Rust語言中非常重要的資料型別,它們用於遍歷集合中的元素,並支援各種操作。在本教學中,我們探討了迭代器的基本概念和常見用法,以Animal為例子,提供了相應的演示程式碼。希望讀者能夠掌握Rust迭代器的相關內容,並且在實際程式設計中得到應用。
以上就是Rust語言從入門到精通系列之Iterator迭代器深入詳解的詳細內容,更多關於Rust Iterator迭代器的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45