11.泛型、trait和生命周期(上)

标题

  • 一、泛型数据的引入
  • 二、改写为泛型函数
  • 三、结构体/枚举中的泛型定义
  • 四、方法定义中的泛型

一、泛型数据的引入

下面是两个函数,分别用来取得整型和符号型vector中的最大值

use std::fs::File;fn get_max_float_value_from_vector(src: &[f64]) -> f64{let mut max = src[0];for &item in src.iter(){if item > max {max = item;}}max
}fn get_max_int_value_from_vector(src: &[i32]) -> i32{let mut max = src[0];for &item in src.iter(){if item > max {max = item;}}max
}
fn main() {let x = vec![12, 21, 78, 56, 77];let y = vec![11.5, 100.3, 1.0, 90.1];println!("max x: {}", get_max_int_value_from_vector(&x));   //max x: 78println!("max y: {}", get_max_float_value_from_vector(&y)); //max y: 100.3
}
  • 只看函数内容,两个函数完成相同
  • 不同的地方在于函数名、返回值和参数
  • 返回值和参数又具有很大的关联性;
  • 这就造成了函数冗余

二、改写为泛型函数

函数get_max_int_value_from_vectorget_max_float_value_from_vector完全可以改写成一个泛型函数,如

fn get_max_value_from_vector<T>(src: &[T]) -> T{}

则代码变成

fn get_max_value_from_vector<T>(src: &[T]) -> T{let mut max = src[0];for &item in src.iter(){if item > max {max = item;}}max
}
fn main() {let x = vec![12, 21, 78, 56, 77];let y = vec![11.5, 100.3, 1.0, 90.1];println!("max x: {}", get_max_value_from_vector(&x));   //max x: 78println!("max y: {}", get_max_value_from_vector(&y)); //max y: 100.3
}

编译报错
在这里插入图片描述

  • 解决方法在5.7 使用trait bounds修复get_max_value_from_vector的错误中进行。

三、结构体/枚举中的泛型定义

  • 下面将坐标值的x,y都改成泛型
struct Point<T>{x: T,y: T,
}enum Option<T> {Some(T),None,
}//两个泛型
enum Result<T, E> {Ok(T),Err(E),
}

四、方法定义中的泛型

struct Point<T>{x: T,y: T,
}impl<T> Point<T>{fn x(&self) -> &T{&self.x}
}
fn main() {let p = Point{x:5, y:10};println!("p.x = {}", p.x());   //p.x = 5
}
  • 在impl后面声明 T,这样就可以在Point<T>上实现的方法中使用;
  • 在impl后声明泛型T ,Rust 就知道Point的尖括号中的类型是泛型而不是具体类型;

下面展示了一个没有在impl 之后(没有尖括号)声明泛型的例子,这里使用了一个具体类型

impl Point<f32> {fn distance_from_origin(&self) -> f32 {(self.x.powi(2) + self.y.powi(2)).sqrt()}
}
  • 代码计算点实例与坐标 (0.0, 0.0) 之间的距离;
  • 这段代码意味着Point<f32> 类型会有一个方法distance_from_origin,
  • 其他不是 f32 类型的Point<T> 实例则没有定义此方法;

结构体定义中的泛型类型参数并不总是与结构体方法签名中使用的泛型是同一类型。
下例的结构体Point<T, U> 上定义了一个方法mixup。这个方法获取另一个 Point 作为参数,而它可能与调用 mixup 的 self 是不同的 Point 类型。这个方法用 self 的 Point 类型的 x 值(类型 T)和参数的 Point 类型的 y 值(类型 W)来创建一个新 Point 类型的实例

struct Point<T, U> {x: T,y: U,
}impl<T, U> Point<T, U> {fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, 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); // p3.x = 5, p3.y = c
}
  • p1是一个有 i32 类型的 x(其值为 5)和 f64 的 y(其值为 10.4)的 Point;
  • p2则是一个有着字符串 slice 类型的 x(其值为 “Hello”)和 char 类型的 y(其值为 c)的 Point;
  • 在p1上以 p2 作为参数调用 mixup 会返回一个 p3,它会有一个 i32 类型的 x;
  • x 来自 p1,并拥有一个 char 类型的 y,y 来自 p2;

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

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

相关文章

代码随想录-Day31

455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都…

Python中的命名空间和作用域:解密变量的可见性和生命周期

在 Python 中&#xff0c;命名空间&#xff08;Namespace&#xff09;和作用域&#xff08;Scope&#xff09;是重要的概念&#xff0c;它们决定了变量和函数的可见性和生命周期。理解命名空间和作用域是编写高效、可维护代码的关键。 基本语法 命名空间 命名空间是一个存储…

新视野大学英语2 词组 6.16

decide between rival options 在互相竞争的选项中做出选择 chinese imperial general 中国帝国将军 on a raid into enemy territory 深入敌方领土突袭 on a raid into&#xff1a;“在进入……的突袭行动中”。 通常指军事行动中快速、秘密地侵入敌人控制的区域&#xff0c…

oracle打补丁

1.备份 su - grid -c "crsctl status res -t" cat /proc/meminfo | grep HugePagesls -lrt /dev/ls -lrt /dev/sd*ls -lrt /dev/asm*cat /etc/udev/rules.d/asm***df -hmountfree -g/etc/security/limits.conf/etc/hosts/etc/selinux/config /etc/pam.d/system-aut…

vs+qt5.0 使用poppler 操作库

Poppler 是一个用来生成 PDF 的C类库&#xff0c;从xpdf 继承而来。vs编译库如下&#xff1a; vs中只需要添加依赖库即可 头文件&#xff1a;

从MySQL到NoSQL:分析传统关系型数据库与NoSQL数据库的协同

引言 数据库是一个系统,用来管理和存储数据的地方。数据在数据库中以一种结构化的方式组织,这样能更容易地查询和处理数据。 关系型数据库是基于关系模型的数据库,它将数据存储在不同的表中,每个表都有各自的独一无二的主键。表与表之间通过共享的数据项相互关联。像MySQ…

windows11 生产力工具配置

一、系统安装 官方windows11.iso镜像文件安装操作系统时&#xff0c;会强制要求联网验证&#xff0c;否则无法继续安装操作系统&#xff0c;跳过联网登录账号的方式为&#xff1a;按下【shiftF10】快捷键&#xff0c;调出cmd命令窗口&#xff0c;输入命令 OOBE\BYPASSNRO 等…

【博客720】时序数据库基石:LSM Tree的辅助优化

时序数据库基石&#xff1a;LSM Tree的辅助优化 场景&#xff1a; LSM Tree其实本质是一种思想&#xff0c;而具体是否需要WAL&#xff0c;内存表用什么有序数据结构来组织&#xff0c;磁盘上的SSTable用什么结构来存放&#xff0c;是否需要布隆过滤器来加快不存在数据的判断等…

Python笔记 - TOML配置文件

TOML&#xff08;Tom’s Obvious, Minimal Language&#xff09;是一种配置文件格式&#xff0c;旨在比JSON、YAML等格式更易读、更人性化。它使用简洁的语法&#xff0c;能清晰地表达复杂的结构&#xff0c;同时保留良好的可读性。本文将介绍TOML的基本语法&#xff0c;提供代…

【UE5|水文章】在UMG上显示帧率

参考视频&#xff1a; https://www.youtube.com/watch?vH_NdvImlI68 蓝图&#xff1a;

数值分析笔记(二)函数插值

函数插值 已知函数 f ( x ) f(x) f(x)在区间[a,b]上n1个互异节点 { x i } i 0 n \{{x_i}\}_{i0}^{n} {xi​}i0n​处的函数值 { y i } i 0 n \{{y_i}\}_{i0}^{n} {yi​}i0n​&#xff0c;若函数集合 Φ \Phi Φ中函数 ϕ ( x ) \phi(x) ϕ(x)满足条件 ϕ ( x i ) y i ( i …

Apollo9.0 PNC源码学习之Routing模块

路由:Routing模块根据请求生成导航信息 输入: 地图数据请求,包括:开始和结束位置输出: 路由导航信息 Routing navigation information0 前言 文件结构: modules/routing/ ├── BUILD ├── common ├── conf ├── core ├── cyberfile.xml ├── dag ├── …

数据结构01 栈及其相关问题讲解【C++实现】

栈是一种线性数据结构&#xff0c;栈的特征是数据的插入和删除只能通过一端来实现&#xff0c;这一端称为“栈顶”&#xff0c;相应的另一端称为“栈底”。 栈及其特点 用一个简单的例子来说&#xff0c;栈就像一个放乒乓球的圆筒&#xff0c;底部是封住的&#xff0c;如果你想…

2024年了,苹果可以通话录音了

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 6月11日凌晨&#xff0c;苹果在WWDC24大会上&#xff0c;密集输出了酝酿多时的AI应用更新。苹果对通话、对话、图…

每日一题44:合作过至少三次的演员和导演

一、每日一题 ---------------------- | Column Name | Type | ---------------------- | actor_id | int | | director_id | int | | timestamp | int | ---------------------- timestamp 是这张表的主键(具有唯一值的列).编写解决方案找出合作过至少三…

力扣 SQL题目

185.部门工资前三高的所有员工 公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。 编写解决方案&#xff0c;找出每个部门中 收入高的员工 。 以 任意顺序 返回结果表。 返回结果格式如下所示。 …

Android studio如何导入项目

打开解压好的安装包 找到build.gradle文件 打开查看gradle版本 下载对应的gradle版本Index of /gradle/&#xff08;镜像网站&#xff09; 下载all的对应压缩包 配置gradle的环境变量 新建GRADLE_HOME 将GRADLE_HOME加入到path中 将项目在Android studio中打开进行配置 将gr…

LM339模块电路故障查询

最近的电路测试中出现一个问题&#xff0c;如果不接液晶屏&#xff0c;LM339输入端是高电平&#xff0c;如果接了液晶屏&#xff0c;输入端就是低电平&#xff0c;即使在输入端加了上拉电阻&#xff0c;还是如前面的结论&#xff0c;如果越过LM339,直接和后级电路连接&#xff…

Python爬虫JS逆向进阶课程

这门课程是Python爬虫JS逆向进阶课程&#xff0c;将教授学员如何使用Python爬虫技术和JS逆向技术获取网站数据。学习者将学习如何分析网站的JS代码&#xff0c;破解反爬虫机制&#xff0c;以及如何使用Selenium和PhantomJS等工具进行模拟登录和数据抓取。课程结合实例演练和项目…

ThinkPHP邮件发送配置教程?怎么配置群发?

ThinkPHP邮件发送安全性如何保障&#xff1f;ThinkPHP如何实现&#xff1f; 无论是用户注册后的验证邮件&#xff0c;还是订单处理的通知邮件&#xff0c;都需要一个可靠的邮件发送机制。AokSend将详细介绍如何在ThinkPHP框架中配置邮件发送功能&#xff0c;并带您逐步了解其中…