【百例RUST - 013】泛型

【百例RUST - 013】泛型

第一章 基础概述

第01节 如果不用泛型

实际案例:

如果我们没有泛型,当为不同的类型定义逻辑相同的函数的时候,可能出现下面的情况

rust 复制代码
fn main(){    
    
    let _a: i8  = return_i8(2i8);
    let _b: i16 = return_i16(2i16);
    let _c: i32 = return_i32(2i32);
    let _d: i64 = return_i64(2i64);

    let _e: u8  = return_u8(2u8);
    let _f: u16 = return_u16(2u16);
    let _g: u32 = return_u32(2u32);
    let _h: u64 = return_u64(2u64);
}

// 如果没有泛型的情况下, 当不同的类型定义逻辑相同的函数的情况下, 可能会出现下面的情况:
fn return_i8(v: i8) -> i8{ v }
fn return_i16(v: i16) -> i16{ v }
fn return_i32(v: i32) -> i32{ v }
fn return_i64(v: i64) -> i64{ v }
fn return_u8(v: u8) -> u8{ v }
fn return_u16(v: u16) -> u16{ v }
fn return_u32(v: u32) -> u32{ v }
fn return_u64(v: u64) -> u64{ v }

这样的操作,会显得代码写出来很繁琐,因为他们逻辑完全相同。

第02节 如果使用泛型

那么我们可以使用泛型完成上述的功能实现。

案例代码

rust 复制代码
fn main(){    
    
    let _a: i8  = return_value(2i8);
    let _b: i16 = return_value(2i16);
    let _c: i32 = return_value(2i32);
    let _d: i64 = return_value(2i64);

    let _e: u8  = return_value(2u8);
    let _f: u16 = return_value(2u16);
    let _g: u32 = return_value(2u32);
    let _h: u64 = return_value(2u64);
}

// 使用泛型的写法
fn return_value<T> (v : T) -> T { v }

第03节 结论

通过上述的案例,我们可以得到下面的几点结论

复制代码
1、泛型是具体类型或者其它属性的抽象代替,用于减少代码的重复。
2、在编写Rust代码时,可以用泛型来表示各种各样的数据类型,等到编译阶段,泛型则被替换成它所代表的的具体的数据类型。

注意事项

复制代码
在 Rust 当中, 使用泛型不会造成持续上的性能损失。

1、因为 Rust 通过在编译时进行泛型代码的单态化来保存效率。(就是在编译时, 把泛型换成了具体的类型)
2、单态化是通过填充编译时使用的具体类型, 将通过代码转换为特定代码的过程

第二章 常用场景

第01节 在结构体中定义泛型

在结构体当中,定义泛型

基础案例代码

rust 复制代码
#[derive(Debug)]
struct Point<T> {
    x : T,
    y : T,
}


fn main(){    
    // 当 point的两个字段都是整型
    let integer: Point<i32> = Point{ x: 1, y:2};
    println!("{:?}", integer);

    // 当 point的两个字段都是浮点型
    let float : Point<f32> = Point { x: 0.99, y: 1.99 };
    println!("{:?}", float);

}


// Point { x: 1, y: 2 }
// Point { x: 0.99, y: 1.99 }

在结构体当中,定义不同的类型

rust 复制代码
#[derive(Debug)]
struct Point<M, N> {
    x : M,
    y : N,
}


fn main(){    
    let a: Point<i32, f64> = Point{x : 1,  y: 2.0};
    println!("{:?}", a);

    let b: Point<f64, i32> = Point{x: 1.99, y:3};
    println!("{:?}", b);
}

//  Point { x: 1, y: 2.0 }
//  Point { x: 1.99, y: 3 }

第02节 在枚举当中定义泛型

系统标准库的案例

在系统库 Option 当中的代码如下:

rust 复制代码
enum  Option<T> {
    Some(T),
    None,
}

同样的案例,还有 Result 的类型,其定义如下:

rust 复制代码
enum  Result<T, E>{
    Ok(T),
    Err(E),
}

下面我们列举,自定义的枚举中,编写的泛型案例

rust 复制代码
#[derive(Debug)]
enum Message<T,U>{
    Msg1(u32),
    Msg2(T),
    Msg3(U),
}


fn main(){
    let _msg1: Message<u32, String>  = Message::Msg1(1u32);
    let _msg2: Message<u8, String> = Message::Msg2(2u8);
    let _msg3: Message<u8, String> = Message::Msg3("hello".to_string());

    println!("{:?}", _msg1);
    println!("{:?}", _msg2);
    println!("{:?}", _msg3);
}

//  Msg1(1)
//  Msg2(2)
//  Msg3("hello")

第03节 在方法当中定义泛型

案例1

rust 复制代码
#[derive(Debug)]
struct Point<T>{
    x : T,
    y : T,
}


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

fn main(){
    let p: Point<i32> = Point{ x:1, y:2};
    println!("{:?}", p); 
    println!("x = {}", p.get_x()); 
    println!("y = {}", p.get_y()); 
}

// Point { x: 1, y: 2 }
// x = 1
// y = 2

案例2

rust 复制代码
#[derive(Debug)]
struct Point<T, U>{
    x : T,
    y : U,
}


impl <T, U> Point<T, U>{
    fn minxup<V, W> (self, other:Point<V,W>) -> Point<T,W>{
        Point { x: self.x, y: other.y }
    }
}

fn main(){
    let p1: Point<i32, f64> = Point {x:5, y:10.04};
    let p2:Point<&str, char>= Point {x:"hello", y:'c'};
    let p3: Point<i32, char> = p1.minxup(p2);

    // 在这里 p1.minxup(p2) ---> 传入到上面的函数中 self=p1  other=p2
    // 因为 self=p1  那么 x 的取值应该是 p1 的取值, 也就是 p3.x = p1.x ---> p3.x = 5
    // 因为 other=p2 那么 y 的取值应该是 p2 的取值, 也就是 p3.y = p2.y ---> p3.y = 'c'

    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}


// p3.x = 5, p3.y = c
相关推荐
考虑考虑8 小时前
cmd局部设置java变量
运维·后端·自动化运维
2601_966949658 小时前
为什么量化策略需要大量历史股票数据?从回测可信度理解数据规模
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
niucloud-admin8 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
滕州市燕猫虎计算机科技工作室个体工商户8 小时前
Java锁
java·开发语言
多加点辣也没关系9 小时前
JavaScript|第31章:表单与控件
开发语言·javascript·ecmascript
菜鸟~noob2339 小时前
【电子战】 第09篇:阵列信号处理——波束形成、MVDR、MUSIC【含matlab代码】
开发语言·matlab·信号处理
ocean21039 小时前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
零依赖极客9 小时前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm
陈随易11 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
新时代牛马11 小时前
cyclictest 毛刺从哪来?从ftrace、latencytop、perf到IRQ/调度延迟定位
android·开发语言·python·kotlin