【Rust自学】10.2. 泛型
10.2 泛型10.2.1. 什么是泛型泛型的主要作用是提高代码的复用性。它们适合处理重复代码问题也可以看成是把数据与算法分离。泛型是具体类型或其他属性的抽象替代。换句话说你写的泛型代码并不是最终代码而更像是一种带有一些占位符的模板。编译器会在编译时把这些占位符替换成具体类型。看个例子fn largestT(list:[T]) - T { //...... }这个函数定义使用了泛型类型参数。T就是所谓的“占位符”。写代码时T可以表示任意类型但在编译时编译器会根据实际用法把T替换成具体类型。这个过程叫做单态化。T是泛型类型参数。实际上你可以使用任意合法标识符作为类型参数名但按惯例通常使用大写字母T代表 Type。选择泛型类型参数名时通常会非常短一个字母往往就够了。如果确实想写长一点使用驼峰命名即可。10.2.2. 函数定义中的泛型用泛型定义函数时需要把泛型类型参数放在函数签名里。泛型类型参数通常用于指定参数类型和返回类型。以 10.1 提取函数以消除重复代码 的代码为例这里做一点泛型修改fn largestT(list: [T]) - T{ let mut largest list[0]; for item in list{ if item largest{ largest item; } } largest }可以把整个函数定义理解成函数largest有一个泛型类型参数T它接收一个切片作为参数切片中的元素类型是T返回值类型也是T。尝试编译一下输出是error[E0369]: binary operation cannot be applied to type T -- src/main.rs:4:17 | 4 | if item largest{ | ---- ^ ------- T | | | T | help: consider restricting type parameter T with trait PartialOrd | 1 | fn largestT: std::cmp::PartialOrd(list: [T]) - T{ | 这里先不讨论原因和修复方法。你只需要知道泛型参数大概就是这样写的。后面的文章会讲解如何指定某个特定的 trait。10.2.3. struct 定义中的泛型结构体中定义的泛型类型参数主要用在其字段上。例如struct PointT { x: T, y: T, } fn main() { let integer Point { x: 5, y: 10 }; let float Point { x: 1.0, y: 4.0 }; }在结构体名称后面加上并在其中写入泛型参数名这个泛型类型就可以应用到结构体的各个字段上。在main中实例化了这个结构体。integer中的两个字段都是i32float中的两个字段都是f64。因为x和y都被声明为T所以实例化后的x和y也必须是同一类型。这两个类型必须保持一致。如果我想让x和y是两种不同的类型呢很简单声明两个泛型类型参数。struct PointT, U { x: T, y: U, } fn main() { let integer Point { x: 5, y: 1.0 }; let float Point { x: 1.0, y: 40 }; }此时实例化后的x和y可以是不同类型当然也可以是相同类型。需要注意的是虽然允许多个泛型类型参数但太多泛型会降低可读性。通常这意味着代码应该被重组为更多、更小的单元。10.2.4. enum 定义中的泛型与结构体很像枚举中的泛型类型参数主要用在其变体中让枚举变体可以持有泛型数据类型。最常见的例子是OptionT和ResultT, E。例如enum OptionT { Some(T), None, } enum ResultT, E { Ok(T), Err(E), }在Option枚举中Some(T)是持有类型为T的值的变体而None变体表示不持有任何值。正因为Option枚举使用了泛型无论这个可能存在的值是什么类型都可以用OptionT来表示同样枚举也可以使用多个泛型类型参数。例如Result枚举使用了T和EOk变体存储TErr变体存储E10.2.5. 方法定义中的泛型方法可以附加在枚举或结构体上。既然枚举和结构体可以使用泛型参数方法当然也可以如下所示struct PointT { x: T, y: T, } implT PointT { fn x(self) - T { self.x } }x方法本质上是一个 getter。为PointT实现方法时需要在impl关键字后面加上T。这表示该实现是针对泛型T的而不是针对某个具体类型。当然如果是为某个具体类型实现方法就不需要那样写impl Pointi32 { fn x1(self) - i32 { self.x } }x1方法只存在于具体类型Pointi32上其他PointT类型没有这个方法类似于 C 中的特化和偏特化。还有一点很重要结构体中的泛型类型参数可以与方法中的泛型类型参数不同。例如struct PointT, U { x: T, y: U, } implT, U PointT, U { fn mixupV, W(self, other: PointV, W) - PointT, W { Point { x: self.x, y: other.y, } } } fn main() { let p1 Point { x: 5, y: 10.4 }; let p2 Point { x: Hello, y: c }; let p3 p1.mixup(p2); println!(p3.x {}, p3.y {}, p3.x, p3.y); }为PointT, U实现了方法mixup。它有两个泛型类型参数V和W。方法中的这两个类型参数与Point中的两个类型参数不同尽管实际类型最终也可能相同。mixup的第二个参数是other它的类型也是Point但这个Point不一定与self所指向的Point使用相同的数据类型因此需要两个新的泛型类型参数。再看返回类型它是PointT, WT来自PointT, UW来自PointV, W。现在看main先声明p1它的两个字段分别是i32和f64再声明p2它的两个字段分别是str字符串切片和char用表示的单个字符。接着使用mixup。p1对应PointT, Up2对应PointV, W。根据它们的字段类型可以推断T是i32U是f64V是strW是char。mixup的返回类型是PointT, W在这个例子中就是Pointi32, char。输出p3.x 5, p3.y c10.2.6. 泛型代码的性能使用泛型编写的代码运行速度与使用具体类型编写的代码一样快。Rust 会在编译时执行单态化把泛型类型替换成具体类型因此执行时不存在类型替换过程。例如fn main() { let integer Some(5); let float Some(5.0); }这里integer是Optioni32float是Optionf64。在编译时编译器会把OptionT展开为Option_i32和Option_f64enum Option_i32 { Some(i32), None, } enum Option_f64 { Some(f64), None, }也就是说泛型定义OptionT被替换成了两个具体类型定义。单态化后的main函数也会变成这样enum Option_i32 { Some(i32), None, } enum Option_f64 { Some(f64), None, } fn main(){ let integer Option_i32::Some(5); let float Option_f64::Some(5.0); }

相关新闻

【Rust自学】10.3. trait Pt.1:trait的定义、约束与实现

【Rust自学】10.3. trait Pt.1:trait的定义、约束与实现

10.3 trait Pt.1:trait的定义、约束与实现 10.3.1. 什么是trait trait 的意思是特征、特质。trait 用来向 Rust 编译器描述某个类型具有哪些能力,以及它可以与其他类型共享哪些行为。trait 以抽象方式定义共享行为。 还有 trait bounds(约束&…

2026/7/23 18:51:03阅读更多 →
【Rust自学】10.4. trait Pt.2:trait作为参数和返回类型、trait bound

【Rust自学】10.4. trait Pt.2:trait作为参数和返回类型、trait bound

10.4 trait Pt.2:trait作为参数和返回类型、trait bound 10.4.1. 把trait作为参数 继续以 10.3 trait Pt.1:trait的定义、约束与实现 中的内容为例: pub trait Summary {fn summarize(&self) -> String; }pub struct NewsArticle {…

2026/7/23 18:51:03阅读更多 →
【Rust自学】10.5. 生命周期 Pt.1:生命周期的定义与意义、借用检查器与泛型生命周期

【Rust自学】10.5. 生命周期 Pt.1:生命周期的定义与意义、借用检查器与泛型生命周期

10.5 生命周期 Pt.1:生命周期的定义与意义、借用检查器与泛型生命周期 10.5.1. 什么是生命周期 Rust 中的每个引用都有自己的生命周期。生命周期的作用是让引用保持有效;换句话说,它就是引用保持有效的作用域。 在大多数情况下&#xff0c…

2026/7/23 18:51:03阅读更多 →
【CTF-WEN-PHP】phps查看源代码并用双重URL编码绕过,admin编码为%25%36%31%25%36%34%25%36%44%25%36%39%25%36%45

【CTF-WEN-PHP】phps查看源代码并用双重URL编码绕过,admin编码为%25%36%31%25%36%34%25%36%44%25%36%39%25%36%45

题目 攻防世界-WEB-PHP2 https://adworld.xctf.org.cn/challenges/list 解题 访问网址 http://61.147.171.105:64825/index.phps admin.split().map(c > % c.charCodeAt(0).toString(16).toUpperCase()).join()%61%64%6D%69%6E%61%64%6D%69%6E.split().map(c > % …

2026/7/23 19:59:27阅读更多 →
告别低效记录!免费又好用的语音转文字软件深度评测,准确率高达98.7%

告别低效记录!免费又好用的语音转文字软件深度评测,准确率高达98.7%

你是否也曾在冗长的会议后,面对堆积如山的录音文件感到头疼?是否在学生时代,为了一字不差地记下老师的板书和口述而手忙脚乱?又或者,作为一名内容创作者,需要将大量的视频、音频采访素材快速转化为文字&…

2026/7/23 19:59:27阅读更多 →
【CTF-MISC-压缩包】脚本实现批量提取压缩包数据

【CTF-MISC-压缩包】脚本实现批量提取压缩包数据

题目 2024年春秋杯网络安全联赛冬季赛 - MISC - 压力大,写个脚本吧 https://www.ichunqiu.com/battalion?t1&r78931 解题思路 打开文件 发现一个压缩包一个txt文件 txt里有一串密文 RkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZH…

2026/7/23 19:59:27阅读更多 →
AI电商头花主图生成:Stable Diffusion商业实践

AI电商头花主图生成:Stable Diffusion商业实践

1. 项目背景与核心价值这个头花产品商业化做图项目源于一个很实际的需求:如何在电商平台上用最低成本批量生成高质量产品展示图。作为从业十年的电商视觉设计师,我深知中小商家在商品主图制作上的痛点——请专业摄影师拍摄成本高,自己拍又难以…

2026/7/23 19:59:27阅读更多 →
[具身智能-629]:从单人闭环到五人协同:云端GPU与边缘专用芯片AI开发的本质鸿沟

[具身智能-629]:从单人闭环到五人协同:云端GPU与边缘专用芯片AI开发的本质鸿沟

很多AI开发者都有一个直观困惑:为什么在电脑、云端随便就能跑通的模型,移植到边缘嵌入式芯片后,bug层出不穷、精度断崖下跌、帧率死活不达标?核心答案并非算力差距,而是两套完全不同的AI工程体系、两种截然不同的研发模…

2026/7/23 19:59:27阅读更多 →
RAG(03)——高质量文本分块

RAG(03)——高质量文本分块

为什么你的RAG效果不佳? 核心痛点 LLM强大,Prompt精心调校,但答案仍不准确检索算法和Embedding已优化,却忽略分块(Chunking) 关键结论 “不恰当的分块给模型喂’坏数据”分块质量决定RAG性能的下限 分块的本质 分块的必要性 LM上下文长度限制-向量检索对语义完整性的…

2026/7/23 19:57:21阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/23 18:58:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/23 18:58:18阅读更多 →