Rust 泛型

泛型函数

 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 {
        if item > largest {
            largest = item;
        }
    }
    
    largest
}

fn main() {
    let numbers = vec![34, 50, 25, 100, 65];
    let result = largest(&numbers);
    println!("最大的数字是 {}", result);
    
    let chars = vec!['y', 'm', 'a', 'q'];
    let result = largest(&chars);
    println!("最大的字符是 {}", result);
}

泛型结构体

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 };
}

泛型结构体的实现:

 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 Point<T> {
    x: T,
    y: T,
}

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

// 只为f32类型实现的方法
impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

fn main() {
    let p = Point { x: 5, y: 10 };
    println!("p.x = {}", p.x());
    
    let p_float = Point { x: 5.0, y: 10.0 };
    println!("距离 = {}", p_float.distance_from_origin());
}

泛型枚举

Rust 标准库中的 Option 和 Result 就是泛型枚举的例子:

1
2
3
4
5
6
7
8
9
enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}

使用 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
// 1. 定义 Log trait
trait Log {
    fn log(&self);
}

// 2. 为 String 实现 Log
impl Log for String {
    fn log(&self) {
        println!("日志内容: {}", self);
    }
}

// 3. 使用 trait 约束的泛型函数
fn print_log<T: Log>(item: T) {
    item.log();
}

fn main() {
    let my_string = String::from("这是一条日志消息");
    
    // 4. 调用泛型函数
    print_log(my_string);  // 输出: 日志内容: 这是一条日志消息
    
    // 5. 也可以直接调用 trait 方法
    let another_string = String::from("直接调用");
    another_string.log();  // 输出: 日志内容: 直接调用
}

关联类型

 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
trait Container {
    type Item;
    
    fn get(&self) -> &Self::Item;
    fn put(&mut self, item: Self::Item);
}

struct MyContainer<T> {
    item: T,
}

impl<T> Container for MyContainer<T> {
    type Item = T;
    
    fn get(&self) -> &T {
        &self.item
    }
    
    fn put(&mut self, item: T) {
        self.item = item;
    }
}

fn main() {
    let mut c = MyContainer { item: 42 };
    println!("{}", c.get());
    c.put(100);
    println!("{}", c.get());
}

默认类型参数

 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
use std::ops::Add;

#[derive(Debug)]
struct Point<T = f32> {
    x: T,
    y: T,
}

impl<T: Add<Output = T>> Add for Point<T> {
    type Output = Self;
    
    fn add(self, other: Self) -> Self::Output {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 1.0, y: 2.0 };
    let p2 = Point { x: 3.0, y: 4.0 };
    let p3 = p1 + p2;
    println!("{:?}", p3);
    
    // 使用默认类型
    let p = Point { x: 1.0, y: 2.0 };
    println!("{:?}", p);
}
0%