2.5 泛型与 trait
泛型和 trait 是 Rust 中用于编写灵活、可重用代码的强大工具。泛型允许开发者编写可以处理多种数据类型的代码,而 trait 则允许开发者定义共享的行为。
2.5.1 泛型
泛型是 Rust 中用于编写可以处理多种数据类型的代码的机制。泛型使用尖括号 (<T>) 表示,其中 T 是类型参数。
1. 泛型函数:
泛型函数可以接受任意类型的参数,并返回任意类型的值:
1
2
3
4
5
6
7
8
9
10
11
|
fn largest<T>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
|
2. 泛型结构体:
泛型结构体可以包含任意类型的字段:
1
2
3
4
5
6
7
8
9
|
struct Point<T> {
x: T,
y: T,
}
fn main() {
let integer_point = Point { x: 5, y: 10 };
let float_point = Point { x: 1.0, y: 4.0 };
}
|
3. 泛型枚举:
泛型枚举可以包含任意类型的变体:
1
2
3
4
5
6
7
8
9
|
enum Option<T> {
Some(T),
None,
}
fn main() {
let some_number = Some(5);
let some_string = Some("a string");
}
|
2.5.2 trait
trait 是 Rust 中用于定义共享行为的机制。trait 类似于其他语言中的接口,但更加强大和灵活。
1. 定义 trait:
trait 使用 trait 关键字定义,其基本语法如下:
1
2
3
4
5
|
trait TraitName {
fn method1(&self) -> ReturnType;
fn method2(&self, param: ParamType) -> ReturnType;
// ...
}
|
TraitName 是 trait 的名称,遵循 Rust 的命名规范。
method1, method2 是 trait 的方法,每个方法都需要指定参数类型和返回类型。
2. 实现 trait:
可以使用 impl 关键字为类型实现 trait:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct StructName {
// ...
}
impl TraitName for StructName {
fn method1(&self) -> ReturnType {
// 方法实现
}
fn method2(&self, param: ParamType) -> ReturnType {
// 方法实现
}
}
|
3. 默认方法:
trait 可以定义默认方法,这些方法可以被实现 trait 的类型覆盖:
1
2
3
4
5
|
trait TraitName {
fn method1(&self) -> ReturnType {
// 默认方法实现
}
}
|
4. trait 作为参数:
trait 可以作为函数参数,允许函数接受任何实现了该 trait 的类型:
1
2
3
|
fn function_name(param: impl TraitName) {
// 函数体
}
|
5. trait bound:
trait bound 用于指定泛型类型必须实现的 trait:
1
2
3
|
fn function_name<T: TraitName>(param: T) {
// 函数体
}
|
2.5.3 代码实例
1. 泛型函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list.iter() {
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);
}
|
2. 泛型结构体:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
fn main() {
let integer_point = Point { x: 5, y: 10 };
println!("integer_point.x = {}", integer_point.x());
let float_point = Point { x: 1.0, y: 4.0 };
println!("float_point.x = {}", float_point.x());
}
|
3. 泛型枚举:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
enum Option<T> {
Some(T),
None,
}
fn main() {
let some_number = Some(5);
let some_string = Some("a string");
match some_number {
Some(x) => println!("some_number is {}", x),
None => println!("some_number is None"),
}
match some_string {
Some(s) => println!("some_string is {}", s),
None => println!("some_string is None"),
}
}
|
4. 定义 trait:
1
2
3
|
trait Summary {
fn summarize(&self) -> String;
}
|
5. 实现 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
|
struct NewsArticle {
headline: String,
location: String,
author: String,
content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
struct Tweet {
username: String,
content: String,
reply: bool,
retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
|
6. trait 作为参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
fn notify(item: impl Summary) {
println!("Breaking news! {}", item.summarize());
}
fn main() {
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};
notify(tweet);
}
|
7. trait bound:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
fn notify<T: Summary>(item: T) {
println!("Breaking news! {}", item.summarize());
}
fn main() {
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};
notify(tweet);
}
|
2.5.4 总结
泛型和 trait 是 Rust 中用于编写灵活、可重用代码的强大工具。泛型允许开发者编写可以处理多种数据类型的代码,而 trait 则允许开发者定义共享的行为。掌握泛型和 trait 的使用技巧,可以编写出更通用、更易维护的 Rust 代码。
以下是一些学习 Rust 泛型和 trait 的资源: