【百例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
相关推荐
红尘散仙4 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
卷毛的技术笔记5 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
isyangli_blog5 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008115 小时前
FastAPI APIRouter
开发语言·python
Benszen5 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆5 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木5 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
喵个咪5 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
杨充6 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~6 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言