Rust泛型编程:从零成本抽象到极致性能
1. 为什么要用泛型
- 用同一套逻辑处理不同类型数据,避免为每种类型重复写函数
- 减少冗余代码,提升表达能力,是一种多态实现
无泛型(啰嗦版)
fnadd_i8(a:i8,b:i8)->i8{a+b}fnadd_i32(a:i32,b:i32)->i32{a+b}fnadd_f64(a:f64,b:f64)->f64{a+b}泛型版(简洁但不能直接编译,需约束)
fnadd<T>(a:T,b:T)->T{a+b}2. 泛型基础语法
T是泛型参数名(惯例用 T=Type)- 使用前必须先声明:
<T>·
- 使用前必须先声明:
fnlargest<T>(list:&[T])->T{...}3. 关键:泛型约束(Trait Bound)
不是所有类型都支持比较、加减,必须用 Trait 限制 T 的行为。
① 比较约束(取最大值)
fnlargest<T:PartialOrd>(list:&[T])->&T{letmutlargest=&list[0];foriteminlist{ifitem>largest{largest=item;}}largest}② 加法约束
fnadd<T:std::ops::Add<Output=T>>(a:T,b:T)->T{a+b}4. 显式指定泛型类型
编译器无法自动推断时,用::<类型>手动指定:
usestd::fmt::Display;fncreate_and_print<T>()whereT:From<i32>+Display{leta:T=100.into();println!("a is: {}",a);}fnmain(){create_and_print::<i64>();// 显式指定 T=i64}5. 结构体泛型
单泛型(同类型字段)
structPoint<T>{x:T,y:T,}// x、y 必须同类型letp=Point{x:1,y:2};多泛型(不同类型字段)
structPoint<T,U>{x:T,y:U,}// x 整数,y 浮点,正常使用letp=Point{x:1,y:1.1};6. 枚举泛型(标准库核心)
Option
enumOption<T>{Some(T),None,}Result<T, E>(错误处理)
enumResult<T,E>{Ok(T),Err(E),}7. 方法中的泛型
为泛型结构体实现方法
structPoint<T>{x:T,y:T}impl<T>Point<T>{// 先声明泛型 Tfnx(&self)->&T{&self.x}}方法自带额外泛型
impl<T,U>Point<T,U>{// V、W 是方法自己的泛型fnmixup<V,W>(self,other:Point<V,W>)->Point<T,W>{Point{x:self.x,y:other.y}}}为具体类型实现方法
// 只有 f32 类型的 Point 才有此方法implPoint<f32>{fndistance_from_origin(&self)->f32{(self.x.powi(2)+self.y.powi(2)).sqrt()}}8. Rust 特色:const 泛型(针对值的泛型)
解决不同长度数组是不同类型的问题,const N: usize代表数组长度。
// T=类型泛型,N=值泛型(数组长度)fndisplay_array<T:std::fmt::Debug,constN:usize>(arr:[T;N]){println!("{:?}",arr);}fnmain(){display_array([1,2,3]);display_array([1,2]);// 长度不同也可通用}9. const fn(编译期执行函数)
允许在编译期计算,常用于配合 const 泛型设置数组 / 缓冲区长度。
constfnadd(a:usize,b:usize)->usize{a+b}constRESULT:usize=add(5,10);// 编译期算出结果const fn + const 泛型
structBuffer<constN:usize>{data:[u8;N],}constfnsize(f:usize)->usize{f*1024}fnmain(){constS:usize=size(4);letbuf=Buffer::<S>{data:[0;S]};}10. 泛型性能:零成本抽象
- Rust 在编译期做单态化:为每种实际类型生成独立代码
- 运行时无额外开销,效率等同于手写多份重复代码
- 代价:编译稍慢、二进制体积稍大
示例:
letinteger=Some(5);letfloat=Some(5.0);编译后会生成:
enumOption_i32{Some(i32),None}enumOption_f64{Some(f64),None}全文核心要点
- 泛型 = 通用代码模板,减少重复
- 泛型必须先声明再使用
- 必须用 Trait 约束类型行为(比较、加法等)
- 支持函数、结构体、枚举、方法泛型
- Rust 独有:const 泛型(处理长度 / 常量)+const fn(编译期计算)
- 零成本抽象,运行时无性能损失
