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
方法后, 所有權被轉移, 該對象就無法被再次使用了.
定義類型本身:
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); }
所以結論是, 如果你的類型是一次性用品, 你可以直接對其實現(xiàn) Iterator
手動實現(xiàn)迭代器
如果你向手動實現(xiàn)類似于容器的東西, 那么它當然不是一次性的. 我們應該仿照 Rust 中對切片的迭代器實現(xiàn).
同時實現(xiàn)會轉移所有權和不會轉移所有權的兩個迭代器對 self
和 &self
都實現(xiàn) IntoIterator
, 這樣就可以做不轉移所有權的迭代了
類型本身:
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
方法, 其實它就相當于對當前切片的引用調用 into_iter
.
其實, 在調用切片引用的 into_iter
方法時, 本質上就是調用的其 iter
方法. 方法的實現(xiàn)是在 iter
內的.
let v = vec![1, 2, 3]; // 下面兩個調用是等價的 let iter1 = v.iter(); let iter2 = (&v).into_iter();
如果你希望實現(xiàn)迭代變量可變的迭代器, 還可以為 &mut T
實現(xiàn) into_iter
, 當然, Rust 內部對于切片的實現(xiàn), 也是這樣的:
let mut v = vec![1, 2, 3]; // 下面兩個調用是等價的 let mutIter = v.iter_mut(); let mutIter = (&mut v).into_iter();
總結
兩種類型:
- 對于一次性使用的類型, 可以直接對其實現(xiàn)迭代器 trait.
- 對于容器, 不應該對容器本身直接實現(xiàn)迭代器, 而是應該單獨創(chuàng)建迭代器類型, 然后對其本身實現(xiàn)
IntoIterator
為了方便用戶使用, 調用之間的實現(xiàn)應該是這樣:
- 實現(xiàn)
T
的IntoIterator
- 實現(xiàn)
&T
的iter
函數(shù), 返回借用的迭代器. - 實訓
&mut T
的iter_mut
函數(shù), 返回可變借用的迭代器. - 對
&T
和&mut T
實現(xiàn)into_iter
函數(shù), 并在內部調用剛剛實現(xiàn)的iter
和iter_mut
函數(shù).
這樣, 用戶就可以直接調用 iter
方法獲得借用的迭代器, 然后使用 map
, filter
等方法進行集合的復雜操作了
到此這篇關于Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法的文章就介紹到這了,更多相關Rust迭代器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
rust中間件actix_web在項目中的使用實戰(zhàn)
這篇文章主要介紹了rust中間件在項目中的使用實戰(zhàn),包括自定義中間件,日志中間件,Default?headers,用戶會話,錯誤處理的用法實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01Rust中non_exhaustive的enum使用確保程序健壯性
這篇文章主要為大家介紹了Rust中non_exhaustive的enum使用確保程序健壯性示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11