元组是一种轻量的方式,可以把固定数量的、类型各异的任意数据组合在一起。元组没有专门的名字;一旦给数据结构起了名字,它就变成了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);