[rust]泛型

8 阅读2分钟

泛型并不会造成程序性能上的损失:

  1. Rust通过在编译时进行泛型代码的单态化来保证效率
  2. 单态化:在编译时获取使用的具体类型,并将通用代码转换为特定代码的过程

在函数中使用

普通函数求最大值

fn main() {
    let arr = vec![3,5,7,2,9,8];
    let max_val = largest_int32(&arr);
    println!("{}",max_val)
}

fn largest_int32(array: &[i32]) -> i32 {
    let mut max = array[0];
    for &i in array {
        if i > max {
            max = i;
        }
    };
    return max;
}

泛型函数求最大值

  1. 泛型约束<T: PartialOrd + Copy>:需要具备能比较大小和能copy的特征
  2. 入参类型和返回值类型都约定为泛型
fn main() {
    let arr = vec![3, 5, 7, 2, 9, 8];
    let max_val = largest_val(&arr);
    println!("{}", max_val)
}

fn largest_val<T: PartialOrd + Copy>(array: &[T]) -> T {
    let mut max = array[0];
    for &i in array {
        if i > max {
            max = i;
        }
    };
    return max;
}

在结构体中使用

只有一种泛型

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

fn main() {
    let integer = Point { x: 1, y: 2 };
    let float = Point { x: 1.50, y: 2.50 };
    println!("{:#?}",integer);
    println!("{:#?}",float)
}

有多种泛型

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

fn main() {
    let integer = Point { x: 1, y: "hello".to_string(), z: 2.0 };
    let float = Point { x: 1.50, y: 'A', z: 1 };
    println!("{:#?}", integer);
    println!("{:#?}", float)
}

在枚举中使用

enum Option<T>{
    Some(T),
    None,
}

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

在方法中使用

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

// 泛型约束:类型必须要有能打印和能克隆的特征
impl<T: Clone + std::fmt::Display, U: Clone + std::fmt::Display> Object<T, U> {
    // self本身包含了<T, U>,所以可以返回<T, U>
    fn creat_same(&self) -> Object<T, U> {
        Object { x: self.x.clone(), y: self.y.clone() }
    }
    
    fn print_self(&self) {
        println!("x = {}, y = {}", self.x, self.y);
    }

    // 方法名后的<V, M>,声明这个是一个泛型方法,入参中会用到V盒M两个不同的类型
    fn creat_random<V, M>(&self,arg_1: V, arg_2: M) -> Object<V, M> {
        Object { x: arg_1, y: arg_2 }
    }
}


fn main() {
    let obj = Object { x: 1, y: "this is a string".to_string() };
    let same_obj = obj.creat_same();
    println!("{:?}", same_obj);

    obj.print_self();

    let random_obj = obj.creat_random(1.0, 'A');
    println!("{:?}", random_obj);
}

或者:增加可读性

impl<T, U> Object<T, U>
where
    T: Clone + std::fmt::Display,
    U: Clone + std::fmt::Display,
{
  //......
}