Rust 基础知识15 泛型<T>

简介

  • 接上回书

泛型概念

  • 泛型可以提高代码复用能力。
  • 泛型用来处理重复代码非常适合,比如排序,针对整数和浮点数的排序几乎是一样的,但是对于Rust 这种强类型语言来说如果没有泛型那么这个排序的方法需要写两个。
  • 泛型类似一种模板,里面会有一些占位符,泛型标记一般用大写字母代替,通常用 T,例如 fn largest<T>(list: &[T]) -> T {...}

函数定义中的泛型 [有未解决的问题]

  • 参数和返回值都可以用泛型代替,举例
// 返回某个类型数组的最大值(这段代码有问题,先参考一下)
fn largest<T> (list: &[T]) -> T {
    let mut largest = list[0];
    for &item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

Struct 定义中的泛型应用

  • 如果遇到多个泛型,可以用不同的大写字母定义泛型,但是需要注意如果泛型参数过多,通常意味着需要重构代码,将代码拆分为多个更小的单元。
  • 举例:
struct Point<T>  {
   x : T,
   y : T,
}

fn main() { 
    let a = Point {x:1 ,y:3};
    let b = Point {x: "林", y: "海"};
    
    println!("{}, {}", a.x, a.y);
    println!("{}, {}", b.x, b.y);
}
image.png

Enum 定义中的泛型

  • 可以让枚举的变体持有泛型的数据类型。
  • 例如: Option<T>, Result<T,E>
enum Option<T> {
    Some(T),
    None,
}

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

方法定义中的泛型

  • 为struct 或 enum实现方法的时候,可在定义中使用泛型。
  • 需要注意的是 impl<T> Point<T> 和 impl Point<f32> 是不同的。
  • 根据举例类型来实现结构体方法时 impl 后面是不需要跟<T> 的,否则需要跟 <T>,举个栗子: (这个例子可能有问题)

struct Point<T>  {
   x : T,
   y : T,
}

// 如果T类型是字符串切片的话
impl Point<&str> {
    // 返回x+y 后的结果
    fn sum_str(&self) -> String {
        format!("{}{}", self.x, self.y)
    }
}
// 如果是其他类型
impl<T> Point<T> {
    fn sum_numeic(&self) -> &T {
        self.x + self.y
    }
}

fn main() { 
    let a = Point {x:1 ,y:3};
    let b = Point {x: "林", y: "海"};
    
    println!("{}, {}", a.x, a.y);
    println!("{}, {}", b.x, b.y);
}


举一个弯弯绕的泛型例子

  • 泛型类型参数可以和方法的泛型类型参数不同的小例子:

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

// 声明一个泛型实现方法:
impl <T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point{x: self.x , y: other.y, }
    }
}

fn main() { 
    let a = Point {x:1 ,y:3};
    let b = Point {x: "林", y: "海"};
    let mixed = a.mixup(b);
    println!("{:?}", mixed);
}
image.png

泛型代码的性能

  • Rust 泛型代码执行的性能是非常好的,因为他会对泛型在使用的时候进行展开编译,举例Some 枚举的泛型编译:
fn main() {
    let integer = Some(5);
    let float = Some(5.1);
}
enum Option_i32 {
    Some(i32),
    None,
}
enum Option_f64 {
    Some(f64),
    None,
}

结束

  • 感谢阅读,下回见。

推荐阅读更多精彩内容