Co

Collect 在 Rust

{other: "%{count} 個練習"}

關於 Collect

要理解 collect 函式,得先知道它是用來求出疊代器結果的。疊代器是一連串的項目,可以和其他疊代器串接在一起。疊代器是_惰性_的,也就是說,除非你呼叫會消耗疊代器的程式碼,否則它們不會執行。這類程式碼包括 for 迴圈和消耗配接器。消耗配接器會處理疊代器中的所有項目,產生某種輸出。

collect 就是其中一種消耗配接器,可以用來產生任何實作了 FromIterator trait 的型別的實例。標準函式庫中的所有集合都實作了這個 trait。由於許多型別都實作了 FromIterator,你需要讓 Rust 知道你想要哪一種集合。舉例來說,如果想從一個字串切片取得 Vec<char>,我們可以在呼叫 collect 時插入型別,像這樣

    let my_chars = "Hello, World!".chars().collect::<Vec<char>>();
// since the item type of the `String::chars()` iterator can be inferred to be `char`, we can omit that information
// let my_chars = "Hello, World!".chars().collect::<Vec<_>>();

那兩個冒號和外層的尖括號(也就是 ::<_>)合稱 turbofish。在這裡,turbofish 的語法比我們需要的還囉嗦。只要在綁定本身指定型別,collect 就能以更少的語法雜訊推斷出該建立什麼集合。

    let my_chars: Vec<char> = "Hello, World!".chars().collect();
// or
// let my_chars: Vec<_> = "Hello, World!".chars().collect();

如果我們想要一個字元順序反轉的 String,可以這樣做

    let rev_chars: String = "Hello, World!".chars().rev().collect();

Rust 的型別推論很強大,有時我們不需要明確地寫出行內標註:

fn get_reversed_chars(phrase: &str) -> Vec<char> {
    phrase.chars().rev().collect()
}

get_reversed_chars 函式的回傳型別讓 collect 函式能推斷出該回傳什麼集合。不過在這裡,我們必須明確寫出 Vec<char> 而不能寫 Vec<_>,因為 Rust 不會對函式簽名進行型別推論。這麼做是為了確保閱讀程式碼的人能快速知道一個函式消耗和回傳哪些型別。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟