Rust:泛型

我们首先看看如何使用泛型定义函数、结构、枚举和方法。然后我们将讨论泛型如何影响代码性能。

泛型函数

使用泛型前的代码

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
28
29
30
31
32
33
34
35
fn largest_i32(list: &[i32]) -> &i32 {
let mut largest = &list[0];

for item in list {
if item > largest {
largest = item;
}
}

largest
}

fn largest_char(list: &[char]) -> &char {
let mut largest = &list[0];

for item in list {
if item > largest {
largest = item;
}
}

largest
}

fn main() {
let number_list = vec![34, 50, 25, 100, 65];

let result = largest_i32(&number_list);
println!("The largest number is {result}");

let char_list = vec!['y', 'm', 'a', 'q'];

let result = largest_char(&char_list);
println!("The largest char is {result}");
}

使用泛型后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn largest<T>(list: &[T]) -> &T {
let mut largest = &list[0];

for item in list {
if item > largest {
largest = item;
}
}

largest
}

fn main() {
let number_list = vec![34, 50, 25, 100, 65];

let result = largest(&number_list);
println!("The largest number is {result}");

let char_list = vec!['y', 'm', 'a', 'q'];

let result = largest(&char_list);
println!("The largest char is {result}");
}

泛型结构体

1
2
3
4
5
6
7
8
9
struct Point<T> {
x: T,
y: T,
}

fn main() {
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };
}

泛型枚举

1
2
3
4
enum Option<T> {
Some(T),
None,
}

泛型方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Point<T> {
x: T,
y: T,
}

impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}

fn main() {
let p = Point { x: 5, y: 10 };

println!("p.x = {}", p.x());
}

使用泛型的代码性能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum Option_i32 {
Some(i32),
None,
}

enum Option_f64 {
Some(f64),
None,
}

fn main() {
let integer = Option_i32::Some(5);
let float = Option_f64::Some(5.0);
}

泛型 Option<T> 被编译器创建的特定定义所取代。由于 Rust 将泛型代码编译为指定每个实例类型的代码,因此使用泛型无需付出任何运行时成本。代码运行时,其执行效果与我们手动复制每个定义时一样。单态化过程使 Rust 的泛型在运行时极其高效。