【百例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
相关推荐
脚踏实地皮皮晨7 小时前
003003001_Grid控件
开发语言·windows·算法·c#·visual studio
十年磨剑走天涯7 小时前
C++ STL 容器操作复杂度速查表
开发语言·c++
万少7 小时前
DeepSeek-V4-Flash 正式版上线了,但这 3 个坑我帮你提前踩了
前端·javascript·后端
明月_清风7 小时前
🚀 Palantir Foundry 本体论实战:当 Ontology 从"知识图谱"进化为"企业操作系统"
前端·后端
always_TT7 小时前
【Python requirements.txt 依赖管理】
开发语言·python
15Moonlight7 小时前
C++进阶(09):特殊类设计
开发语言·c++
宁风NF8 小时前
JavaScript:网络请求与前端通信
开发语言·前端·javascript·网络·学习·ecmascript
明月_清风8 小时前
从概念到代码:用 Ontology 构建你的第一个知识图谱
前端·后端
Logintern098 小时前
py文件开头为什么需要加:from __future__ import annotations
开发语言·python
Python私教8 小时前
Django 6.1 邮件配置大改:旧项目如何平稳升级?
后端·python·django