Rust的泛型基础与实践

在这里插入图片描述

什么是泛型?

想象一下,我们想定义一个函数,它可以用来计算任意类型数据的最大值。如果我们只考虑整数,我们可以这样写:

fn max(a: i32, b: i32) -> i32 {if a > b {a} else {b}
}

但是,如果我们还想比较浮点数、字符串甚至自定义类型呢?每次都写一个新的函数显然不是一个好主意。这时,泛型就派上用场了。

泛型允许我们定义一个函数或数据结构,而不指定具体的类型。直到我们使用它的时候,才会确定具体的类型。

泛型函数的例子

fn max<T: PartialOrd>(a: T, b: T) -> T {if a > b {a} else {b}
}
  • T: PartialOrd: 这里的 T 代表一个泛型类型,PartialOrd 是一个 trait,表示实现了它的类型可以进行部分比较(比如大于小于)。
  • a: T, b: T: 函数接受两个类型为 T 的参数。
  • -> T: 函数返回类型也是 T

这样,我们就可以用这个函数来比较各种类型的数据了:

fn main() {let num1 = 10;let num2 = 20;println!("max(num1, num2) = {}", max(num1, num2));let str1 = "hello";let str2 = "world";println!("max(str1, str2) = {}", max(str1, str2));
}

泛型结构体的例子

struct Point<T> {x: T,y: T,
}fn main() {let integer_point = Point { x: 5, y: 10 };let float_point = Point { x: 3.14, y: 2.718 };
}

这里我们定义了一个 Point 结构体,它的坐标 xy 可以是任意类型。

泛型枚举的例子

enum Option<T> {Some(T),None,
}

Option 枚举是一个非常常用的泛型,表示一个值可能存在也可能不存在。

泛型实现

impl<T> Point<T> {fn x(&self) -> &T {&self.x}
}

这里我们为 Point 结构体实现了 x 方法,用于获取 x 坐标。

泛型约束

除了 PartialOrd,Rust 还提供了很多其他的 trait,用于约束泛型类型的行为。例如:

  • Copy: 表示类型可以被拷贝。
  • Clone: 表示类型可以被克隆。
  • Debug: 表示类型可以被调试打印。

为什么要用泛型?

  • 代码复用: 可以写出更通用、可复用的代码。
  • 类型安全: 编译器可以帮助我们检查类型错误。
  • 表达能力强: 可以定义更灵活的数据结构和算法。

总结

泛型是Rust中一个非常强大的特性,它允许我们编写更加通用、灵活和安全的代码。通过泛型,我们可以定义适用于多种类型的函数、结构体和枚举。

练习

  • 试着实现一个泛型的栈数据结构。
  • 实现一个泛型的链表。
  • 尝试使用不同的泛型约束来限制泛型类型的行为。

=============
参考答案
好的,我们来一起完成那些练习,并更深入地理解Rust的泛型。

练习1:实现一个泛型的栈数据结构

struct Stack<T> {data: Vec<T>,
}impl<T> Stack<T> {fn new() -> Self {Stack { data: Vec::new() }}fn push(&mut self, element: T) {self.data.push(element);}fn pop(&mut self) -> Option<T> {self.data.pop()}fn is_empty(&self) -> bool {self.data.is_empty()}
}
  • 解释:
    • 我们定义了一个泛型结构体 Stack<T>,其中 T 代表栈中元素的类型。
    • new 方法用于创建一个空的栈。
    • push 方法用于将元素添加到栈顶。
    • pop 方法用于从栈顶移除元素,并返回一个 Option<T>,表示元素可能存在或不存在。
    • is_empty 方法用于判断栈是否为空。

练习2:实现一个泛型的链表

struct Node<T> {value: T,next: Option<Box<Node<T>>>,
}struct LinkedList<T> {head: Option<Box<Node<T>>>,
}impl<T> LinkedList<T> {fn new() -> Self {LinkedList { head: None }}// ... 其他方法,比如插入、删除、查找等
}
  • 解释:
    • Node 结构体表示链表中的一个节点。
    • LinkedList 结构体表示整个链表。
    • 这里只给出了一个基本的链表结构,你可以根据需要添加更多的功能,比如插入、删除、查找等。

练习3:使用不同的泛型约束

fn print_debug<T: Debug>(t: T) {println!("{:?}", t);
}fn copy_and_modify<T: Copy>(t: T) -> T {let mut t = t;// 可以修改t,因为T实现了Copy traitt
}
  • 解释:
    • Debug trait 用于格式化打印,print_debug 函数可以打印实现 Debug trait 的任何类型。
    • Copy trait 用于表示类型可以被拷贝,copy_and_modify 函数可以复制一个类型为 T 的值,并对副本进行修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/454604.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【每日刷题】Day142

【每日刷题】Day142 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1219. 黄金矿工 - 力扣&#xff08;LeetCode&#xff09; 2. 980. 不同路径 III - 力扣&#xff0…

C++20中头文件ranges的使用

<ranges>是C20中新增加的头文件&#xff0c;提供了一组与范围(ranges)相关的功能&#xff0c;此头文件是ranges库的一部分。包括&#xff1a; 1.concepts: (1).std::ranges::range:指定类型为range&#xff0c;即它提供开始迭代器和结束标记(it provides a begin iterato…

MP9928模块分析

MP9928 是一款高性能的同步降压 DC/DC 转换器控制器 IC&#xff0c;具有宽输入范围。以下是其操作和关键特性的总结&#xff1a; 概述 电流模式控制&#xff1a;MP9928 使用电流模式、可编程开关频率控制架构&#xff0c;通过外部 N 沟道 MOSFET 开关来调节输出电压。 反馈和…

PRCV2024:可信AI向善发展与智能文档加速构建

目录 0 写在前面1 GAI时代的挑战&#xff1a;图像内容安全1.1 图像篡改与对抗攻击1.2 生成式图像鉴别1.3 人脸鉴伪模型体验1.4 助力可信AI向善发展 2 GAI时代的机遇&#xff1a;大模型加速器2.1 TextIn大模型加速器2.2 通用文档解析2.3 文本向量模型 3 总结 0 写在前面 中国模…

认识一下:__asm { int 80h; LINUX - sys_fork }

这行代码 __asm { int 80h; LINUX - sys_fork } 使用了汇编语言的语法来直接调用 Linux 系统调用 fork。下面是对这行代码的详细解析&#xff1a; 代码解析 __asm: 这是一个用于嵌入汇编代码的指令&#xff0c;通常在 C 或 C 代码中使用&#xff0c;允许开发者直接插入汇编语言…

信息安全系统设计第七周

文章目录 密码系统设计学习内容AI 对学习内容的总结&#xff08;1分&#xff09;要求总结 第10章&#xff1a;身份认证和PKI理论基础第11章&#xff1a;实战PKI对 AI 总结的反思与补充&#xff08;2分&#xff09;要求反思与补充 学习思维导图&#xff08;2分&#xff09;要求思…

Pytorch 实现图片分类

CNN 网络适用于图片识别&#xff0c;卷积神经网络主要用于图片的处理识别。卷积神经网络&#xff0c;包括一下几部分&#xff0c;输入层、卷积层、池化层、全链接层和输出层。 使用 CIFAR-10 进行训练&#xff0c; CIFAR-10 中图片尺寸为 32 * 32。卷积层通过卷积核移动进行计…

告别微信封号!学会这5招,让你的账号坚不可摧

在这个信息爆炸的时代&#xff0c;无论是工作沟通、社交互动还是获取信息&#xff0c;微信都扮演着极其重要的角色。但是&#xff0c;随着微信平台规则的日益严格&#xff0c;账号被封的风险也随之增加。今天&#xff0c;我们就来聊聊如何有效防止 微信被封&#xff0c;让你的账…

【RL Latest Tech】安全强化学习(Safe RL):理论、方法与应用

&#x1f4e2;本篇文章是博主强化学习&#xff08;RL&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…

Python | Leetcode Python题解之第486题预测赢家

题目&#xff1a; 题解&#xff1a; class Solution:def PredictTheWinner(self, nums: List[int]) -> bool:length len(nums)dp [0] * lengthfor i, num in enumerate(nums):dp[i] numfor i in range(length - 2, -1, -1):for j in range(i 1, length):dp[j] max(num…

uniapp结合uview-ui创建项目

准备工作&#xff1a; 下载HBuilderX;官网地址:HBuilderX-高效极客技巧 安装node.js;官网地址&#xff1a;Node.js — 在任何地方运行 JavaScript,下载所需版本&#xff0c;安装后配置好环境变量即可 方式一&#xff08;NPM安装方式&#xff09;&#xff1a; 1、打开开发者…

代码随想录-哈希表-两个数组的交集

题目与思路 这个题目可以用大小为1000的数组&#xff0c;因为限制了变量大小。我用的是set&#xff0c;感觉这个才是本意。 下面代码是用set实现的hash结构。先用set1存储nums1中的去重元素&#xff0c;然后用set2存储结果集 最后将set转为array用了两种方式&#xff0c;一是…

LINUX设备OTA时无法从HTTP服务器(TOMCAT)下载文件

疑难问题排查记录 问题 linux设备作为http客户端&#xff0c;执行OTA前先从HTTP服务器下载bin固件&#xff0c;测试nginx没有问题&#xff0c;nodejs编写的HTTP服务器也没有问题&#xff0c;而软件同事使用的Tomcat则无法成功下载。 排查经过 首先利用chrome浏览器测试下载…

WebGl 实现图片平移、缩放和旋转

1.图片平移 在WebGL中实现图片平移&#xff0c;可以通过修改顶点着色器中的顶点位置来实现。平移的基本思想是将每个顶点的位置向量沿着指定的方向&#xff08;通常是x轴和y轴&#xff09;进行平移。在顶点着色器中&#xff0c;可以通过添加或减去一个统一的偏移量&#xff08…

「AIGC」n8n AI Agent开源的工作流自动化工具

n8n AI Agent 是一个利用大型语言模型(LLMs)来设计和构建智能体(agents)的工具,这些智能体能够执行一系列复杂的任务,如理解指令、模仿类人推理,以及从用户命令中理解隐含意图。n8n AI Agent 的核心在于构建一系列提示(prompts),使 LLM 能够模拟自主行为。 传送门→ …

C++:stack 和 queue 的使用和模拟实现

使用 要注意&#xff0c;stack 和 queue 没有迭代器。 stack void teststack() {stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);cout << st.size() << endl;while (!st.empty()){cout << st.top() << " ";…

电机编码器

旋转式编码器 链接: 野火编码器 单圈&#xff0c;多圈绝对式编码器 在单圈绝对值编码器中&#xff0c;单圈并不表示编码器机械转动的圈数&#xff0c;而是指断电记忆的范围。实际上&#xff0c;机械转动是可以无限制地进行圈数的&#xff0c;但是断电记忆仅限于一圈的范围内…

构建后端为etcd的CoreDNS的容器集群(二)、下载最新的etcd容器镜像

在尝试获取etcd的容器的最新版本镜像时&#xff0c;使用latest作为tag取到的并非最新版本&#xff0c;本文尝试用实际最新版本的版本号进行pull&#xff0c;从而取到想的最新版etcd容器镜像。 一、用latest作为tag尝试下载最新etcd的镜像 1、下载镜像 [rootlocalhost opt]# …

bash之基本运算符

一.算术运算符 vim test.sh #!/bin/basha10 b20valexpr $a $b echo "a b : $val"valexpr $a - $b echo "a - b : $val"valexpr $a \* $b echo "a * b : $val"valexpr $b / $a echo "b / a : $val"valexpr $b % $a echo "b % a …

《重置MobaXterm密码并连接Linux虚拟机的完整操作指南》

目录 引言 一、双击MobaXterm_Personal_24.2进入&#xff0c;但是忘记密码。 那么接下来请跟着我操作。 二、点击此链接&#xff0c;重设密码。 三、下载完成后&#xff0c;现在把这个exe文件解压。注意解压要与MobaXterm_Personal_24.2.exe在同一目录下哦&#xff0c;不然…