Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法
在 Rust 中, for 語句的執(zhí)行依賴于類型對于 IntoIterator 的實現(xiàn), 如果某類型實現(xiàn)了這個 trait, 那么它就可以直接使用 for 進行循環(huán).
直接實現(xiàn)
在 Rust 中, 如果一個類型實現(xiàn)了 Iterator, 那么它會被同時實現(xiàn) IntoIterator, 具體邏輯是返回自身, 因為自身就是迭代器.
但是如果自身就是迭代器的話, 就意味著自身必須存儲迭代狀態(tài), 例如當前迭代的位置. 如果是這樣的話, 迭代器就只能被使用一次. 況且自身直接被傳入 into_iter 方法后, 所有權(quán)被轉(zhuǎn)移, 該對象就無法被再次使用了.
定義類型本身:
struct IntRange {
current: i32,
step: i32,
end: i32
}直接為其實現(xiàn)迭代器:
impl Iterator for IntRange {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.end {
return None;
} else {
let current = self.current;
self.current += self.step;
return Some(current);
}
}
}使用該類型:
let range = IntRange { current: 0, step: 1, end: 10 };
for value in range {
println!("v: {}", value);
}所以結(jié)論是, 如果你的類型是一次性用品, 你可以直接對其實現(xiàn) Iterator
手動實現(xiàn)迭代器
如果你向手動實現(xiàn)類似于容器的東西, 那么它當然不是一次性的. 我們應(yīng)該仿照 Rust 中對切片的迭代器實現(xiàn).
同時實現(xiàn)會轉(zhuǎn)移所有權(quán)和不會轉(zhuǎn)移所有權(quán)的兩個迭代器對 self 和 &self 都實現(xiàn) IntoIterator, 這樣就可以做不轉(zhuǎn)移所有權(quán)的迭代了
類型本身:
struct IntRange {
step: i32,
end: i32
}兩個迭代器:
struct IntRangeIter<'a> {
range: &'a IntRange,
current: i32,
}
struct IntRangeIntoIter {
range: IntRange,
current: i32,
}兩個迭代器實現(xiàn):
impl Iterator for IntRangeIter<'_> {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.range.end {
return None;
} else {
let current = self.current;
self.current += self.range.step;
return Some(current);
}
}
}
impl Iterator for IntRangeIntoIter {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.range.end {
return None;
} else {
let current = self.current;
self.current += self.range.step;
return Some(current);
}
}
}實現(xiàn)返回兩種迭代器的 IntoIterator:
impl<'a> IntoIterator for &'a IntRange {
type Item = i32;
type IntoIter = IntRangeIter<'a>;
fn into_iter(self) -> Self::IntoIter {
IntRangeIter {
range: self,
current: 0
}
}
}
impl IntoIterator for IntRange {
type Item = i32;
type IntoIter = IntRangeIntoIter;
fn into_iter(self) -> Self::IntoIter {
IntRangeIntoIter {
range: self,
current: 0
}
}
}使用它:
let range = IntRange { step: 1, end: 10 };
// 可以使用引用來進行 for 循環(huán)
for value in &range {
println!("v: {}", value);
}
// 也可以直接對其進行 for 循環(huán)
for value in range {
println!("v: {}", value);
}切片對迭代的實現(xiàn)
我們知道, Rust 的切片有一個 iter 方法, 其實它就相當于對當前切片的引用調(diào)用 into_iter.
其實, 在調(diào)用切片引用的 into_iter 方法時, 本質(zhì)上就是調(diào)用的其 iter 方法. 方法的實現(xiàn)是在 iter 內(nèi)的.
let v = vec![1, 2, 3]; // 下面兩個調(diào)用是等價的 let iter1 = v.iter(); let iter2 = (&v).into_iter();
如果你希望實現(xiàn)迭代變量可變的迭代器, 還可以為 &mut T 實現(xiàn) into_iter, 當然, Rust 內(nèi)部對于切片的實現(xiàn), 也是這樣的:
let mut v = vec![1, 2, 3]; // 下面兩個調(diào)用是等價的 let mutIter = v.iter_mut(); let mutIter = (&mut v).into_iter();
總結(jié)
兩種類型:
- 對于一次性使用的類型, 可以直接對其實現(xiàn)迭代器 trait.
- 對于容器, 不應(yīng)該對容器本身直接實現(xiàn)迭代器, 而是應(yīng)該單獨創(chuàng)建迭代器類型, 然后對其本身實現(xiàn)
IntoIterator
為了方便用戶使用, 調(diào)用之間的實現(xiàn)應(yīng)該是這樣:
- 實現(xiàn)
T的IntoIterator - 實現(xiàn)
&T的iter函數(shù), 返回借用的迭代器. - 實訓(xùn)
&mut T的iter_mut函數(shù), 返回可變借用的迭代器. - 對
&T和&mut T實現(xiàn)into_iter函數(shù), 并在內(nèi)部調(diào)用剛剛實現(xiàn)的iter和iter_mut函數(shù).
這樣, 用戶就可以直接調(diào)用 iter 方法獲得借用的迭代器, 然后使用 map, filter 等方法進行集合的復(fù)雜操作了
到此這篇關(guān)于Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法的文章就介紹到這了,更多相關(guān)Rust迭代器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust使用lettre實現(xiàn)郵件發(fā)送功能
這篇文章主要為大家詳細介紹了Rust如何使用lettre實現(xiàn)郵件發(fā)送功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
詳解Rust調(diào)用tree-sitter支持自定義語言解析
使用Rust語言結(jié)合tree-sitter庫解析自定義語言需要定義語法、生成C解析器,并在Rust項目中集成,具體步驟包括創(chuàng)建grammar.js定義語法,使用tree-sitter-cli工具生成C解析器,以及在Rust項目中編寫代碼調(diào)用解析器,這一過程涉及到對tree-sitter的深入理解和Rust語言的應(yīng)用技巧2024-09-09
Rust 中單線程 Web 服務(wù)器的實現(xiàn)
本文用Rust構(gòu)建單線程Web服務(wù)器,通過HTTP/TCP處理請求,返回hello.html或404.html,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-06-06

