Rust泛型编程:从零成本抽象到极致性能

1. 为什么要用泛型

  • 同一套逻辑处理不同类型数据,避免为每种类型重复写函数
  • 减少冗余代码,提升表达能力,是一种多态实现

无泛型(啰嗦版)

rust 复制代码
fn add_i8(a:i8, b:i8) -> i8 { a + b }
fn add_i32(a:i32, b:i32) -> i32 { a + b }
fn add_f64(a:f64, b:f64) -> f64 { a + b }

泛型版(简洁但不能直接编译,需约束)

rust 复制代码
fn add<T>(a:T, b:T) -> T {
    a + b
}

2. 泛型基础语法

  • T 是泛型参数名(惯例用 T=Type)
    • 使用前必须先声明<T>·
rust 复制代码
fn largest<T>(list: &[T]) -> T { ... }

3. 关键:泛型约束(Trait Bound)

不是所有类型都支持比较、加减,必须用 Trait 限制 T 的行为。

① 比较约束(取最大值)

rust 复制代码
fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

② 加法约束

rust 复制代码
fn add<T: std::ops::Add<Output = T>>(a:T, b:T) -> T {
    a + b
}

4. 显式指定泛型类型

编译器无法自动推断时,用 ::<类型> 手动指定:

rust 复制代码
use std::fmt::Display;

fn create_and_print<T>() where T: From<i32> + Display {
    let a: T = 100.into();
    println!("a is: {}", a);
}

fn main() {
    create_and_print::<i64>(); // 显式指定 T=i64
}

5. 结构体泛型

单泛型(同类型字段)

rust 复制代码
struct Point<T> {
    x: T,
    y: T,
}
// x、y 必须同类型
let p = Point { x: 1, y: 2 }; 

多泛型(不同类型字段)

rust 复制代码
struct Point<T, U> {
    x: T,
    y: U,
}
// x 整数,y 浮点,正常使用
let p = Point { x: 1, y: 1.1 };

6. 枚举泛型(标准库核心)

Option

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

Result<T, E>(错误处理)

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

7. 方法中的泛型

为泛型结构体实现方法

rust 复制代码
struct Point<T> { x: T, y: T }

impl<T> Point<T> { // 先声明泛型 T
    fn x(&self) -> &T {
        &self.x
    }
}

方法自带额外泛型

rust 复制代码
impl<T, U> Point<T, U> {
    // V、W 是方法自己的泛型
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point { x: self.x, y: other.y }
    }
}

具体类型实现方法

rust 复制代码
// 只有 f32 类型的 Point 才有此方法
impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

8. Rust 特色:const 泛型(针对值的泛型)

解决不同长度数组是不同类型 的问题,const N: usize 代表数组长度。

rust 复制代码
// T=类型泛型,N=值泛型(数组长度)
fn display_array<T: std::fmt::Debug, const N: usize>(arr: [T; N]) {
    println!("{:?}", arr);
}

fn main() {
    display_array([1,2,3]);
    display_array([1,2]); // 长度不同也可通用
}

9. const fn(编译期执行函数)

允许在编译期计算,常用于配合 const 泛型设置数组 / 缓冲区长度。

rust 复制代码
const fn add(a: usize, b: usize) -> usize {
    a + b
}
const RESULT: usize = add(5, 10); // 编译期算出结果

const fn + const 泛型

rust 复制代码
struct Buffer<const N: usize> {
    data: [u8; N],
}
const fn size(f: usize) -> usize { f * 1024 }

fn main() {
    const S: usize = size(4);
    let buf = Buffer::<S> { data: [0; S] };
}

10. 泛型性能:零成本抽象

  • Rust 在编译期做单态化:为每种实际类型生成独立代码
  • 运行时无额外开销,效率等同于手写多份重复代码
  • 代价:编译稍慢、二进制体积稍大

示例:

rust 复制代码
let integer = Some(5);
let float = Some(5.0);

编译后会生成:

rust 复制代码
enum Option_i32 { Some(i32), None }
enum Option_f64 { Some(f64), None }

全文核心要点

  1. 泛型 = 通用代码模板,减少重复
  2. 泛型必须先声明再使用
  3. 必须用 Trait 约束类型行为(比较、加法等)
  4. 支持函数、结构体、枚举、方法泛型
  5. Rust 独有:const 泛型 (处理长度 / 常量)+ const fn(编译期计算)
  6. 零成本抽象,运行时无性能损失
相关推荐
微学AI8 小时前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
豆瓣鸡8 小时前
算法日记 - Day3
java·开发语言·算法
韭菜炒鸡肝天9 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
Aaron - Wistron10 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
笨鸟先飞,勤能补拙10 小时前
AI 赋能网络安全领域深度剖析
网络·人工智能·windows·安全·web安全·网络安全·github
Dxy123931021610 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
我上去就是一套QWER然后等待复活11 小时前
Windows 清理 CC Switch 并恢复官方 Codex CLI 登录流程(完整记录)
windows
05664611 小时前
Python康复训练——常用标准库
开发语言·python·学习
骊城英雄11 小时前
基于C#+avalonia ui实现的跨平台点胶机灌胶监控控制上位机软件
开发语言·ui·c#
吾儿良辰11 小时前
一个被BCL遗忘的高性能集合:C# CircularBuffer<T>深度解析
开发语言·windows·c#