范型数据类型
- 一般使用T作为类型参数名称
- 适用于结构体、枚举、函数等
- 支持多个类型
- 可以限定方法实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| fn largest<T>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
struct Point<T,U> {
x: T,
y: U,
}
|
Rust 通过单态化保证运行效率。将通用代码转化为特定代码。
Trait 定义共同行为
- 类似于高级语言中的接口
- 可以指定默认实现
- 不同的类型可以冲在该方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| pub trait Summary {
fn summarize(&self) -> String;
}
// 包含默认实现
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
// 范型中,实现了Summary Trait 的类型T
pub fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
// 实现了 Summary + Display 类型的参数
pub fn notify(item: &(impl Summary + Display)) {}
// where 语句,指定Trait
fn some_function<T, U>(t: &T, u: &U) -> i32
where
T: Display + Clone,
U: Clone + Debug,
{}
|
声明周期确保引用有效
目的:确保悬垂引用
悬垂引用
1
2
3
4
5
6
7
8
9
10
11
| fn main() {
let r;
{
let x = 5;
// r 引用了x,x 尝试离开作用域,
r = &x;
}
println!("r: {}", r);
}
|
生命周期注解
1
2
3
4
5
6
7
8
9
10
11
| &i32 // 引用
&'a i32 // 带有显式生命周期的引用
&'a mut i32 // 带有显式生命周期的可变引用
struct ImportantExcerpt<'a> {
part: &'a str,
}
fn longest<'a>(x: &'a str, y: &str) -> &'a str {
x
}
|
编译器采用三条规则来判断引用何时不需要明确的注解:
- 编译器为每一个是引用参数都分配了一个生命周期参数
- 如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数:
fn foo<'a>(x: &'a i32) -> &'a i32
。 - 如果方法有多个输入生命周期参数并且其中一个参数是 &self 或 &mut self,说明是个对象的方法 (method)(译者注:这里涉及 rust 的面向对象参见 17 章),那么所有输出生命周期参数被赋予 self 的生命周期;