Rust 泛型:<T> 类型参数与 trait
泛型让同一套代码适配多种数据类型。<T> 是类型占位符,trait(中文常称“特征”,即规定类型必须具备的一组方法)是行为契约。按以下步骤掌握核心用法。
- 识别 占位符作用。
<T>代表“任意具体类型”,编译器在编译期将T静态替换为真实类型代码,运行时无额外性能损耗。 - 对比 传统写法。普通函数只能处理单一固定类型,泛型函数通过一套模板处理整数、浮点数、字符串等多种类型,消除重复代码。
- 确认 命名规则。
T取自英文Type首字母,多个参数按T、U、V顺序排列。
- 创建 测试环境。在终端运行
cargo new generics_guide并进入 生成的目录。 - 定义 泛型结构体。打开
src/main.rs,写入 带占位符的结构:struct Point<T> { x: T, y: T, } - 填充 实际数据。在
main函数中声明 变量:let p1 = Point { x: 10, y: 20 }; let p2 = Point { x: 5.5, y: 6.6 }; - 检查 编译结果。执行
cargo build,终端显示零错误,结构体成功推断并适配不同基础类型。
- 编写 比较逻辑。添加 获取较大值的函数:
fn largest<T>(a: T, b: T) -> T { if a > b { a } else { b } } - 捕获 编译拦截。运行
cargo check,终端报错binary operation > cannot be applied。编译器提示:不知道T是否支持比较,直接拒绝生成可执行文件。 - 绑定 trait 约束。在
<T>后追加: PartialOrd。PartialOrd是标准库提供的比较契约,表示“该类型支持大于小于运算”。修改签名:fn largest<T: PartialOrd>(a: T, b: T) -> T { - 补充 显示能力。直接打印返回值会触发
E0277错误,需追加std::fmt::Display(表示类型能被格式化转为字符串)。重写 完整逻辑:fn largest<T: PartialOrd + std::fmt::Display>(a: T, b: T) -> T { let result = if a > b { a } else { b }; println!("Selected: {}", result); result }
- 拆分 冗长签名。当约束条件叠加,函数声明行会超出合理阅读宽度。将约束移至函数体前方,启用
where语法。 - 重构 代码布局。改写 声明结构:
fn largest<T>(a: T, b: T) -> T where T: PartialOrd + std::fmt::Display, { if a > b { a } else { b } } - 调用 多类型验证。在
main中传入 浮点数largest(34.5, 12.1);与字符largest('z', 'a');,终端正确输出各类型最大值。
- 声明 自定义契约。在文件顶部定义 业务方法集:
trait Report { fn generate(&self) -> String; // 强制要求实现者返回文本描述 } - 落实 类型实现。为
u32整数添加 契约支持:impl Report for u32 { fn generate(&self) -> String { format!("ID Generated: {}", self) } } - 设计 泛型处理器。创建 接收泛型入参的函数,并用
where限制 行为边界:fn process_report<T>(data: T) where T: Report, { let msg = data.generate(); println!("{}", msg); } - 执行 完整流程。替换
main函数为最终入口:fn main() { let id: u32 = 8801; process_report(id); // let raw_text = "hello"; // process_report(raw_text); // 取消注释将触发编译错误:&str 未实现 Report } - 验证 输出结果。在 终端运行
cargo run,控制台打印ID Generated: 8801。泛型保障类型灵活,trait 保障行为确定,编译器在构建阶段拦截所有非法调用。

暂无评论,快来抢沙发吧!