11.1 泛型数据类型
11.1.1 函数的泛型
- 注意:泛型的比较适用于实现了
std::cmp::PartialOrd
trait 的数据类型
11.1.2 结构体的泛型
- 结构体的泛型可以使用多个泛型类型参数
11.1.3 枚举的泛型
- 类似于结构体,枚举的泛型也可以使用多个泛型类型参数
11.1.4 方法的泛型
- 定义方法时可以为泛型指定限制(只有指定类型的数据可以使用该方法)
- 结构体定义的泛型参数可以与结构体方法签名的泛型参数不同,从而可以交叉使用不同的泛型类型
11.1.5 泛型代码的性能
11.2 Trait:定义共同行为
11.2.1 定义 trait
trait
定义了不同类型的共享功能trait
中可以只提供方法签名(后跟分号),而提供具体的实现是可选的trait
的具体实现由每个实现该trait
的类型来定义并提供,且每个实现都使用相同的方法签名trait
体中可以有多个方法,一行一个方法签名且都以分号结尾
11.2.2 实现 trait
impl Xxx_trait for Yyy
:为 Yyy 类型实现 Xxx_trait(使用for
)- 实现
trait
的限制:只有当至少一个trait
或者要实现trait
的类型位于 crate 的本地作用域时,才能为该类型实现trait
;不能为外部类型实现外部trait
11.2.3 trait 的默认实现
- 默认实现是可选的
- 默认实现允许调用相同
trait
中的其他方法,哪怕这些方法没有默认实现(也就是只需重新实现对应部分即可)
11.2.4 trait 作为参数(一):impl Trait 语法
- impl Bound 语法用于(不)相同类型的参数
11.2.5 trait 作为参数(二):Trait Bound 语法
- trait bound 语法用于相同类型的参数
trait_1 + trait_2 + ...
:实现多个不同trait
相加(同时实现)- 可通过
where
从句简化 trait bound
11.2.6 返回实现了 trait 的类型
11.2.7 使用 trait bound 有条件地实现方法
- 可以有条件地只为那些实现了特定
trait
的类型来实现方法、trait
- 举例:带【Display】
trait
条件实现【xxx】方法fn
:impl<T: Display> Pair<T> { fn xxx() }
- 举例:带【Display】
trait
条件实现【ToString】trait
:impl<T: Display> ToString for T
11.3 生命周期(一种泛型):确保引用是有效的
11.3.1 悬垂引用与借用检查器
- 生命周期避免了悬垂引用
11.3.2 函数中的泛型生命周期
11.3.3 生命周期注解语法
- 生命周期注解并不改变任何引用的生命周期的长短,而是用于描述了多个引用生命周期相互的关系
- 生命周期注解:生命周期参数名称以撇号(')开头,其名称通常全是小写
&i32
:引用&'a i32
:带有显式生命周期的引用&'a mut i32
:带有显式生命周期的可变引用
11.3.4 函数签名中的生命周期注解
- 函数签名中的生命周期注解:在函数名和参数列表间的尖括号中声明泛型生命周期(lifetime)参数,就像泛型类型(type)参数一样
- 当在函数中使用生命周期注解时,这些注解出现在函数签名中,而不存在于函数体中的任何代码中
- 类似于函数
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str
中,泛型生命周期 'a 的具体生命周期等同于 x 和 y 的生命周期中较小的那一个(核心概念!)
11.3.5 函数返回引用时需要关联生命周期
- 注意:若返回引用,则需要将多个参数与其返回值的生命周期进行关联,否则最好返回有所有权的值!
11.3.6 结构体中的引用类型:需要生命周期注解
- 定义包含引用类型的结构体:需要为结构体定义中的每一个引用类型添加生命周期注解
11.3.7 生命周期省略(Lifetime Elision)
- 生命周期省略规则(一):编译器为每一个(输入、输出)引用参数都分配了一个生命周期参数
- 生命周期省略规则(二):如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数
- 生命周期省略规则(三):如果方法有多个输入生命周期参数并且其中一个参数是
&self
或&mut self
,那么所有输出生命周期参数被赋予 self 的生命周期(该规则只适用于方法fn
中)
11.3.8 方法(fn)中的生命周期注解
- 实现带有生命周期的结构体实现方法
fn
时,类似于泛型类型参数的语法,比如:impl<'a> xxx_struct<'a>
- 根据生命周期省略(三),无需在方法
fn
签名中使用生命周期注解
11.3.9 静态生命周期
- 静态生命周期
'static
:其生命周期能够存活于整个程序期间 - 所有的字符串字面值都拥有
'static
生命周期 - 使用
'static
前,思考这个引用是否真的在整个程序的生命周期里都有效