元組是一種輕量的方式,能把一組型別各異、數量固定的資料聚集在一起。元組沒有特定的名稱;為資料結構命名後,它就變成了 struct。元組的欄位沒有名稱,而是透過解構或依位置來存取。
元組一律使用元組運算式建立:
// pointless but legal
let unit = ();
// single element
let single_element = ("note the comma",);
// two element
let two_element = (123, "elements can be of differing types");
元組可以有任意數量的元素。
我們可以透過解構來存取元組的元素。這只是把變數名稱指定給元組中的個別元素,並在過程中消耗掉整個元組。
let (elem1, _elem2) = two_element;
assert_eq!(elem1, 123);
也可以透過數字位置索引來存取元組的元素。索引一如往常,從 0 開始。
let notation = single_element.0;
assert_eq!(notation, "note the comma");
你之後也會需要處理元組結構體。和一般結構體一樣,它們是具名型別;但和一般結構體不同的是,它們的欄位是匿名的。它們的語法和一般的元組語法非常相似。解構與依位置存取兩者都可以使用。
struct TupleStruct(u8, i32);
let my_tuple_struct = TupleStruct(123, -321);
let neg = my_tuple_struct.1;
let TupleStruct(byte, _) = my_tuple_struct;
assert_eq!(neg, -321);
assert_eq!(byte, 123);
匿名元組的所有欄位一律都是公開的。不過,元組結構體的每個欄位各自擁有可見性,預設為私有,就和標準結構體的欄位一樣。你可以用 pub 修飾詞把欄位設為公開,就和標準結構體一樣。
// fails due to private fields
mod tuple { pub struct TupleStruct(u8, i32); }
fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); }
// succeeds: fields are public
mod tuple { pub struct TupleStruct(pub u8, pub i32); }
fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); }
你正在開發一款目標為低功耗嵌入式系統的遊戲,需要撰寫幾個便利函式,供遊戲的其他部分使用。
商是除法的輸出。
fn divmod(dividend: i16, divisor: i16) -> (i16, i16)
範例:
assert_eq!(divmod(10, 3), (3, 1));
你的老闆保證,這對啟用螢幕緩衝區最佳化會有幫助。
疊代器是會公開 Iterator trait 所定義之方法的項目。那份文件相當詳盡,因為疊代器提供了許多方法;以下是最相關的幾個特性:
enumerate方法,會為每個值回傳一個元組(i, val)
filter方法,會用閉包判斷是否要產出疊代器中的某個元素map方法,會用閉包修改疊代器中的元素由於你的函式可以執行在任何種類的疊代器上,因此它使用impl來表示這是 trait 實例,而不是單純的項目。同樣地,<Item=T>語法只是表示疊代器產生什麼種類的項目並不重要;你的函式可以產生任何疊代器的偶數元素。
fn evens<T>(iter: impl Iterator<Item=T>) -> impl Iterator<Item=T>
範例:
let mut even_ints = evens(0_u8..);
assert_eq!(even_ints.next(), Some(0));
assert_eq!(even_ints.next(), Some(2));
assert_eq!(even_ints.next(), Some(4));
assert_eq!(even_ints.next(), Some(6));
let mut evens_from_odds = evens(1_i16..);
assert_eq!(evens_from_odds.next(), Some(1));
assert_eq!(evens_from_odds.next(), Some(3));
assert_eq!(evens_from_odds.next(), Some(5));
assert_eq!(evens_from_odds.next(), Some(7));
為了方便對應,你有一個元組結構Position:
struct Position(i16, i16);
你需要為Position實作一個manhattan方法,回傳該位置與原點(Position(0, 0))之間的曼哈頓距離。
impl Position {
fn manhattan(&self) -> i16
}
範例:
assert_eq!(Position(3, 4).manhattan(), 7);