19_rust的泛型

提取函数消除重复代码

fn get_largest(list: &[i32]) -> i32 {
    let mut max_num = list[0];
    for &i in list {
        if i > max_num {
            max_num = i;
        }
    }
    max_num
}
fn main() {
    let n1 = vec![12, 24, 56, 11];
    let max_num = get_largest(&n1);
}

泛型

泛型:提高代码复用能力。用于处理重复代码。
泛型是具体类型或其它属性的抽象代替:

  • 代码非最终代码,是一种模板,含“占位符”<T>
  • 编译器编译时将占位符替换为具体类型

如 fn get_max<T>(list: &[T]) -> <T> {}
类型参数:常用一个字母,使用CamelCase,T:type的缩写。

使用泛型

函数定义中的泛型

泛型函数:参数类型、返回类型。

fn get_max<T>(list: &[T]) -> <T> {}

Struct中使用泛型

struct st1<T> {
    x: T,
    y: T,
}
struct st2<T, U> {
    x: T,
    y: U,
}
fn main() {
    let a1 = st1 {x: 5, y: 6};
    let a2 = st1 {x: 5, y: 6.0};// 报错expected integer, found floating-point number
    let a3 = st2 {x: 5, y: 6.0};
}

Enum定义中使用泛型

可让枚举的变体持有泛型数据类型,如之前用过的:

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

方法的定义中使用泛型

可为struct或enum实现方法的代码中,可使用泛型。

struct st1<T> {
    x: T,
    y: T,
}
impl<T> st1<T> { // 这是针对泛型T来实现的方法
    fn func1(&self) -> &T {
        &self.x
    }
}

impl st1<i32> { // 这个实现仅对i32类型才有其他类型的st1没有
    fn func_i32(&self) -> &i32 {
        &self.x
    }
}

注:把T放在impl关键字后,表示类型T上实现方法。只针对具体类型实现方法(其余类型没有)
另外struct里的泛型类型参数可和方法的泛型类型参数不同

struct St2<T, U> {
    x: T,
    y: U,
}
impl<T, U> St2<T, U> {
    fn mix<V, W>(self, o: St2<V, W>) -> St2<T, W> {
        St2 { // 返回值类型来自两个对象的各一个字段
            x: self.x,
            y: o.y,
        }
    }
}
fn main() {
    let a1 = St2 {x: 5, y: 6.0};
    let a2 = St2 {x: 'c', y: "str"};
    let a3 = a1.mix(a2);
    println!("x:{} y:{}", a3.x, a3.y);
}
// 输出结果 x:5 y:str

泛型代码的性能

使用泛型的代码和使用具体类型的代码运行速度一样。
因为编译时进行单态化(monomorphization):在编译是将泛型替换为具体类型的过程。

fn main() {
    let i = Some(5);
    let f = Some(5.0);
}
// 编译时进行展开,相当于如下代码
enum Option_i32 {
    Some(i32),
    None,
}
enum Option_f64 {
    Some(f64),
    None,
}
fn main() {
    let i = Option_i32::Some(5);
    let f = Option_f64::Some(5.0);
}
posted @ 2023-10-26 00:47  00lab  阅读(2)  评论(0编辑  收藏  举报