Rust高階 用之即棄的iterator

2021-10-05 15:17:04 字數 1879 閱讀 8281

iterator在rust或者pytho等多種語言裡都只能做一次迭代。比如在rust中迭代到容器末尾後就會返回乙個none此時再繼續遍歷也沒有意義了,同時也沒有提供方法可以重置。只能用之即棄了。

這個特性在std::io::lines表現十分典型。來看下面**:

fn compare(src : &str, des : &str);

let f_des = file::open(des);

let mut f_des = match f_des ;

let buf_src = bufreader::new(&f).lines();

for src_line in buf_src ", src);

println!("des line: {}", &des_line.unwrap());}}

}

上面**開啟了兩個檔案,並且比較檔案每行內容的差異。分別讀取兩個檔案後,通過for迴圈巢狀,實現逐行對比。感覺很正常,編譯通過,執行...  然鵝出問題了。

src line: src0   des line: des0

src line: src0 des line: des1

src line: src0 des line: des2

src line: src0 des line: des3

和期望結果不同,內層的迴圈只迴圈了一次。

為了找出原因,我們首先來檢視lines的定義:

原來實現的是iterator介面。

這意味著內層迴圈在迭代器移動容器末尾後,當外層迴圈在執行到內層時,迭代器已是末尾,所以不再執行內層迴圈。

如何解決這個問題?

可以通過vec來間接避免迭代器用之即棄的問題。修改下**:

fn compare1(src : &str, des : &str);

let f_des = file::open(des);

let mut f_des = match f_des ;

let buf_des = bufreader::new(&f_des).lines();

let buf_src = bufreader::new(&f).lines();

let mut vec_des = vec::new();

for des_line in buf_des

for src_line in buf_src ", src);

for des_line in &vec_des ", src);

println!("des line: {}", &des_line);}}

}

為什麼使用了vec就解決了問題,吃個鴨脖,我們繼續來分析問題。

***********************************====路過的分割線*********************************************

繼續查詢intoiterator就會發現這個東東是對iterator的包裝。

pub trait intoiterator where self::intoiter::item == self::item
for迴圈中通過intoiterator返回乙個迭代器,對vec的迴圈等價於

let result = match intoiterator::into_iter(&v) ", x); }

none => break,}},

};

這樣保證了即使外層巢狀了迴圈,內層執行時都是重新生成乙個迭代器,從而避免了迭代器用之即棄的問題。

以上個人觀點,如果有錯誤請不吝指教。歡迎討論,共同學習。

Rust高階篇 Rust之如何組織專案目錄

1.含義packages cargo提供的讓我們建立,測試和分享crates的工具.crates 提供類庫或可執行檔案的模組樹 modules and use 管理和組織路徑,及其作用域和訪問許可權 paths 如結構體 structs 函式 function 或模組 module 等事物的命名方式...

C巨集高階應用之

在巨集定義中經常看到 和 現在講一下他們的用法 1,是連線符 用於將兩個引數連線在一起 例如 define a x,y x y 則 a he llo 結果是hello define link a my a 則 link god 相當於 mygod 是一種分隔連線方式 他的作用是先分隔 然後強制連線 ...

C 高階應用之Microsoft Vsa引擎篇

引擎實現部分 using system using system.collections using system.io using system.reflection using microsoft.visualbasic.vsa using microsoft.vsa 作者注 需要增加對micr...