Rust之泛型、特性和生命期(一):基本概念

Rust基础 - 函数 Rust基础 - 函数摘要函数 摘要 函数在所有编程语言中,是最基本的要素之一。它将具有特定目的语句,表达式组合在一起,实现特定功能。函数基本组成包括函数类型说明符fn,函数名,参数列表,返回值和函数体。 函数 fn sum(n1: i32, n2: i32) -> i32 { let sum = n1 + n2; sum } 如上代码所示,是Rust中函数最常见的一种表现... 阅读详情

开发环境

  • Windows 10
  • Rust 1.69.0

 

  • VS Code 1.77.3

 项目工程

这里继续沿用上次工程rust-demo

泛型、特性和生命期 

每种编程语言都有有效处理概念重复的工具。在Rust中,一个这样的工具就是泛型:具体类型或其他属性的抽象替身。我们可以表达泛型的行为或它们与其他泛型的关系,而不知道在编译和运行代码时它们的位置会是什么。

函数可以接受一些泛型的参数,而不是像i32或String这样的具体类型,就像函数接受未知值的参数一样,对多个具体值运行相同的代码。事实上,我们已经在之前的章节的Option<T>、向量Vec<T>和HashMap<K, V>,以及Result<T, E>中使用了泛型。在这一章中,你将探索如何用泛型定义你自己的类型、函数和方法!

首先,我们将回顾如何提取一个函数以减少代码的重复。然后,我们将使用同样的技术,从两个仅在参数类型上有差异的函数中提取出一个泛型函数。我们还将解释如何在结构和枚举的定义中使用泛型。

然后你将学习如何使用特质以通用方式定义行为。你可以将特质与泛型结合起来,约束泛型只接受那些具有特定行为的类型,而不是任何类型。

最后,我们将讨论生命期:各种泛型,给编译器提供关于引用如何相互关联的信息。生命期允许我们给编译器提供足够的关于借用值的信息,这样它就可以确保引用在更多的情况下是有效的,而不需要我们的帮助。

通过提取一个函数来消除重复

泛型允许我们用一个代表多种类型的占位符来替换特定的类型,以消除代码的重复。在深入研究泛型语法之前,让我们先看看如何通过提取一个用代表多个值的占位符替换特定值的函数,以一种不涉及泛型类型的方式来消除重复。然后,我们将应用同样的技术来提取一个泛型的函数! 通过研究如何识别可以提取到一个函数中的重复代码,你将开始识别可以使用泛型的重复代码。

我们从示例1中的短程序开始,它可以找到一个数组种的最大的数字。

文件名: src/main.rs

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let mut largest = &number_list[0];

    for number in &number_list {
        if number > largest {
            largest = number;
        }
    }

    println!("The largest number is {}", largest);
}

示例1 寻找数组中的最大数字

我们在变量number_list中存储一个数组,并将数组中第一个数字的引用放在一个名为maximum的变量中。然后我们遍历数组中的所有数字,如果当前数字大于存储在largest中的数字,则替换该变量中的引用。然而,如果当前的数字小于或等于到目前为止所看到的最大的数字,变量就不会改变,代码就会转到数组中的下一个数字。在考虑了数组中的所有数字后,largest应该指的是最大的数字,在本例中是100。

我们现在的任务是在两个不同的数组中找出最大的数字。为此,我们可以选择复制清单10-1中的代码,在程序中的两个不同地方使用相同的逻辑,如示例2所示。

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let mut largest = &number_list[0];

    for number in &number_list {         // 遍历数组
        if number > largest {
            largest = number;
        }
    }

    println!("The largest number is {}", largest);

    let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];

    let mut largest = &number_list[0];

    for number in &number_list {         // 遍历数组
        if number > largest {
            largest = number;
        }
    }

    println!("The largest number is {}", largest);
}

示例2:寻找两个数组中最大数字的代码

虽然这段代码是有效的,但重复代码是繁琐的,而且容易出错。当我们想改变代码时,我们还得记住在多个地方更新代码。

为了消除这种重复,我们将通过定义一个函数来创建一个抽象,该函数可以对参数中传递的任何整数的数组进行操作。这个解决方案使我们的代码更加清晰,并使我们能够抽象地表达寻找数组中最大数字的概念。

在示例3中,我们将寻找最大数字的代码提取到一个名为maximum的函数中。然后,我们调用这个函数来寻找示例2中两个数组中的最大数字。我们也可以在将来可能出现的任何其他i32值的数组中使用这个函数。

fn largest(list: &[i32]) -> &i32 {          // 通用函数,用于计算数组种的最大值
    let mut largest = &list[0];

    for item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);             // 调用函数largest
    println!("The largest number is {}", result);

    let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];
 
    let result = largest(&number_list);            // 调用函数largest
    println!("The largest number is {}", result);
}

示例3:查找两个数组中最大数字的抽象代码

最大的函数有一个叫做list的参数,它代表了我们可能传入函数的任何具体的i32切片。因此,当我们调用该函数时,代码在我们传入的具体数值上运行。

综上所述,以下是我们将代码从示例2改为示例3的步骤:

  • 识别重复的代码。
  • 将重复的代码提取到函数的主体中,并在函数签名中指定该代码的输入和返回值。
  • 更新两个重复代码的实例,以调用该函数代替。

接下来,我们将使用这些相同的步骤,用泛型来减少代码的重复。就像函数主体可以对抽象list而不是具体数值进行操作一样,泛型允许代码对抽象类型进行操作。

例如,假设我们有两个函数:一个是在i32值的切片中寻找最大的项目,一个是在char值的切片中寻找最大的项目。我们将如何消除这种重复呢?让我们拭目以待!

本章重点

  • 泛型的基本概念
  • 函数抽象:提取重复代码
  • 求取数组中的最大数方法
「Rust笔记」Rust之知识点拾遗汇总 1、const 常量必须指定类型 const MAX:i32 = 1000_1000; 2、函数返回值 fn func_3(x: i32) -> i32 { //返回值必须声明 x + 1 //没有分号,认为是表达式,返回值,不需要return } fn func_4(x: i32) -> i32 { //返回值必须声明 x + 1; //有分号,认为是陈述,不返回值,值为() } 3、break 可以返回值 ```cpp let mut cou 阅读详情

相关推荐

[rust整理笔记]一门比较有前景的编程语言--rust

Rust是mozilla推出的一款系统级的编程语言,其两大特点在于零开销抽象和安全性。 rust特点 类似于C++,Rust的定位是一款系统级语言,它所有特点: 1.零开销抽象 2.没有gc 3.内存模型没有高度封装 4.语法干净正交,没有C++那么繁琐。 5.安全性。Rust语法引入所有权和生命期概念,在编译期就能检查出一部分内存管理错误,这是rust的一个杀手锏的特性。 6.现代语言特性。语言...

图解AI 1万+

【Rust日报】2024-03-21 ​Rust 1.77.0 版本发布

Rust 1.77.0 版本发布Rust 团队宣布了 Rust 编程语言的最新版本 1.77.0。这个版本虽然相对小,但包含了一系列改进,使得 Rust 语言更加强大和易用。新特性和改进C-string 字面量: Rust 现在支持 C-string 字面量(例如 c"abc"),它们会扩展为内存中以 null 字节终止的字符串,类型为 &'static CStr。这对于编写与需要 nul...

Rust语言学习交流 1282

robomimic实验复现全流程指南:从数据集下载到训练视频生成

本文提供了RoboMimic实验复现的完整实战指南,重点解析了从数据集下载、配置文件定制到模型训练与评估的全流程。以tool_hang任务为例,详细说明了环境准备、数据获取、训练监控及视频生成等关键步骤,并针对常见问题给出了排查方案,帮助研究者高效完成机器人模仿学习实验的闭环验证。

2w3e4r5t6y的博客 1031

【Rust日报】2024-02-19 Linux 内核准备升级至 Rust 1.77

Linux 内核准备升级至 Rust 1.77Linux 6.8 内核已经升级至 Rust 1.75,而最新的补丁则将内核的 Rust 代码迁移到 Rust 1.76,并准备好迎接即将发布的 Rust 1.77。 Rust 1.77 稳定了内核 Rust 代码使用的单字段 "offset_of" 功能,并添加了一个"--check-cfg" 选项,内核 Rust 代码未来可能会过渡到这个选项。这符...

Rust语言学习交流 1369

基于ZYNQ7020芯片(黑金开发板AX7020)之AXI-FULL DDR的PL与PS交互操作。

在该工程中我们使用了PS端的串口接收功能,PS端串口接收和发送分别有一个64字节的FIFO,但是因为串口接收阈值设置为16,所以固定接收16个字节数据后才会发生中断。此测试工程得到以前知识的总结和各大网友的支持,只希望可以为学习的你更进一步,大家一起学习才是真的开心。加油,国产芯片之路。

landyjzlai的博客 3190

从DDH到FastANI:原核生物分类黄金标准的进化史与技术对比

本文系统梳理了原核生物分类标准从DDH到FastANI的四次技术革命,详细解析了95%相似度阈值的科学依据及应用场景。通过对比DDH、16S rRNA、ANI和FastANI的技术特点与性能指标,为微生物研究者提供基因组分类的实战指南,并展望第三代测序时代的分类新挑战。

weixin_29275257的博客 412

【教程】Flutter与Rust完美交互,无需手写FFI代码

Flutter与Rust完美交互,无需手写FFI代码,使用flutter_rust_bridge自动生成

每天进步一点点 1万+

基于51单片机扫地机器人(全套Proteus仿真+原理图+程序+说明书)

(内含源程序代码,原理图,仿真,讲解视频,元件清单等,【精品】值得推荐!!!扫地机器人是以单片机为主控制器。通过单片机控制小车行驶、除尘、蜂鸣。扫地机器人使用双电机驱动,以提高整车运动的平稳性;在智能车进驶过程中,采用双超声波模块实现避障。

2301_76434107的博客 1895

LongCat-2.0革命性突破:美团1.6万亿参数MoE大模型完全指南

在人工智能领域,大模型技术正在以前所未有的速度发展。今天,我们要深入探讨美团推出的**LongCat-2.0**——这款拥有**1.6万亿参数**的**MoE(Mixture of Experts)大模型**,它不仅代表了技术上的重大突破,更展现了国产AI芯片在大规模训练和推理方面的卓越能力。对于想要了解**大模型技术前沿**、**MoE架构优势**以及**AI加速器应用**的开发者和技术爱好者来

gitblog_00873的博客 733

从 SAP Gateway 旧 add-ons 卸载到 SAP S/4HANA 转换的清理路线

摘要: SAP Gateway系统的维护难点往往源于历史遗留组件的堆积,而非OData服务本身的复杂性。早期系统为支持多种服务类型而安装的各类add-ons(如IW_SCS、IW_CNT、GW_CORE等),随着系统升级和团队更替逐渐成为技术负债。自SAP NetWeaver 7.40起,核心功能已整合至SAP_GWFND组件,使架构显著简化。在向S/4HANA迁移时,需重点清理已废弃的add-ons(如IW_SCS、IW_GIL等),但必须谨慎验证其关联服务是否仍被调用。组件清理需结合系统日志和调用链分析

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 423

用 XCO 库一键找出某个 ABAP 类的全部子类

ABAP XCO库子类枚举技术解析 本文介绍了在ABAP项目中如何利用XCO库高效获取类的继承层次结构。传统方法使用CL_ABAP_CLASSDESCR或手动维护映射表存在效率低、易遗漏的问题。新方法通过XCO库的IF_XCO_AO_CLASS接口,可简洁地获取父类的所有子类(包括间接子类)。 核心API链式调用: 获取类句柄:xco_cp_abap=>class() 导航子类集合:subclasses->all 获取结果:get()返回类引用表或get_names()返回类名列表 典型应用场景

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 127

良辰带你详解Rust 异步递归解决方案详解

Rust 的异步递归需要通过引入间接层(装箱)来解决 Future 大小未知的问题。根据你的项目需求和环境约束,可以选择使用宏、手动装箱或 Rust 1.77+ 的原生支持。每种方案都有其适用场景,理解其背后的原理有助于做出合适的选择。

程序员良辰 1151

【我的Android进阶之旅】Android自定义View实现一个游戏摇杆,来实现监听遥动的方向或者监听摇动的角度的功能

一、需求描述 去年有个需求,需要使用自定义View实现一个游戏摇杆,来识别上下左右摇动的方向。 有点类似下面这样的王者荣耀游戏摇杆的效果 二、业界已有的参考资料 在下面这篇博客介绍了如何自定义游戏摇杆 2.1 博客介绍 Android自定义摇杆 2.1.1 功能 支持自适应大小 支持2个方向、4个方向、8个方向的摇动监听 支持摇动角度获取 可选回调模式 支持可摇动区域自定义 支持摇杆自定义 支持设置图片、色值、Shape图形 2.1.2 效果图 2.1.3 设置回调方式 setCallBac

字节卷动 1409

Rust之泛型、特性和生命期(一):通用数据类型

当定义一个使用泛型的函数时,我们将泛型放在函数的签名中,在这里我们通常会指定参数和返回值的数据类型。这样做使我们的代码更加灵活,为我们的函数的调用者提供更多的功能,同时防止代码重复。继续我们的最大函数,示例4显示了两个函数,它们都能找到一个片断中的最大值。然后我们将把它们合并成一个使用泛型的函数。文件名:src/main.rsfn largest_i32(list: &[i32]) -> &i32 { // largest_i32 函数largest。

wing的专栏 1000

Qt版Dalsa线扫相机的采集Demo

Qt Dalsa

追赶时代的博客 604

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Rust之泛型、特性和生命期(三):验证有生存期的引用

Rust之泛型、特性和生命期,验证有生存期的引用,函数,结构,方法等生存期注释

wing的专栏 918

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Rust之泛型、特性和生命期(二):Traits:定义共同的行为

Rust之泛型、特性和生命期(三),Traits:定义共同的行为

wing的专栏 1923

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【Rust 笔记】09-特型与泛型

【Rust 笔记】09-特型与泛型

feiyan的博客 614

泛型与关联类型

翻译自:https://thomashartmann.dev/blog/on-generics-and-associated-types/泛型与关联类型和其他我学过的语言相比较,Rus...

Rust语言学习交流 799

Rust 中生命周期与泛型的组合使用:让“时间”也成为类型的一部分

在 Rust 里,类型刻画“形”,生命周期刻画“时”。把两者组合使用,等于把“可替换的数据形态”与“可证明的存活关系”一起编码进 API 契约。掌握 HRTB、GAT、T: 'a'a: 'b等关键工具,并在工程中遵守“最小暴露、边界拥有化、变型友好”的设计纪律,你就能写出既安全、又高性能、还能长期维护的 Rust 代码。把时间也纳入类型系统,是 Rust 与众不同的真正力量。🚀。

2501_94030986的博客 602

Rust:生命周期

讲解Rust的生命周期,显式标注,省略规则,生命周期约束等

博客网站 https://async-area.com 1017

嵌入式开发者必须掌握的10个Rust核心特性(错过等于落后五年)

掌握Rust嵌入式开发关键特性,提升系统安全与性能。涵盖裸机编程、零成本抽象、内存管理等核心方法,适用于物联网、实时系统等场景。十大特性助力开发者高效构建可靠固件,值得收藏。

IterLoom的博客 770

2411rust,76~79

2411rust,76~79

个人进步之路 801

Rust基本类型

Rust 基本类型见下表,后面分节介绍。表2-1 Rust类型。

weixin_43219667的博客 994

rust 的所有权

假设是 go 语言来实现同样的代码,程序没有任何问题,s1 和 s2 实际指向的同样的字符串,可以正常打印 s1,赋值前后压根不会对 s1 产生影响。快速解决上述问题的方案,是将赋值的方式修改为引用赋值,就像下面这样,给 s2 赋值的是 s1 的引用,这样 s2 就不能接管 neojos 字符串的所有权,引用赋值过程就属于。比如下面的例子,s2 指向了 s1 的可修改引用,s3 试图通过从 s2 取值,那么,s1 变量所拥有的值会发生转移吗?由 s1 转移给了 s2,然后 s1 变成了未初始化的状态。

小知识折射大智慧 1266

Rust编程之旅启航:《Rust编程与项目实战》第一章学习心得与见解

通过第一章的学习,Rust给我留下了深刻的印象,它不仅是编程语言的进化,更是编程思想的跃迁。它诞生于对现有编程语言缺陷的反思,旨在结合低级别控制与高级抽象的优势,同时解决内存安全问题,这让我意识到,Rust不仅仅是C或C++的替代品,它代表着一种全新的编程范式。在深入阅读《Rust编程与项目实战》的第一章“Rust基础”之后,我的编程视野仿佛被一扇崭新的大门打开,这不仅仅是对一门新语言的学习,更是一场对编程思维模式的革新之旅。下面,我将分享我的学习心得,希望能为即将踏上Rust征途的你提供一点光亮。

wypdao的专栏 717
上一篇: Rust之错误处理(三):panic!还是不要panic!
下一篇: Rust之泛型、特性和生命期(一):通用数据类型
枫★曦
博客等级 码龄19年 251粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值