【百例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
相关推荐
曹牧3 小时前
Spring:@RequestMapping
java·后端·spring
霸道流氓气质3 小时前
SpringBoot+LangChain4j+Ollama实现本地大模型语言LLM的搭建、集成和示例流程
java·spring boot·后端
iiiiyu4 小时前
常用API(SimpleDateFormat类 & Calendar类 & JDK8日期 时间 日期时间 & JDK8日期(时区) )
java·大数据·开发语言·数据结构·编程语言
故事和你914 小时前
洛谷-数据结构1-4-图的基本应用2
开发语言·数据结构·算法·深度优先·动态规划·图论
qq_12084093714 小时前
Three.js 工程向:Clock、deltaTime 与固定步长主循环
开发语言·javascript·ecmascript
小菜同学爱学习4 小时前
夯实基础!MySQL数据类型进阶、约束详解与报错排查
开发语言·数据库·sql·mysql
源码站~4 小时前
基于机器学习的社交媒体舆情分析系统
开发语言·python
浮游本尊4 小时前
MES 实施计划从新建到自动流转:三条入口、一套存储、两类驱动
后端
Nyarlathotep01134 小时前
LockSupport工具类
java·后端