当前位置: 首页 > news >正文

Rust核心:【所有权】相关知识点

rust在内存资源管理上采用了(先进优秀?算吗)但特立独行的设计思路:所有权。这是rust的核心,贯穿在整个rust语言的方方面面,并以此为基点来重新思考和重构软件开发体系。

涉及到的概念点:借用,引用,生命周期

借用(borrowing)

这里就要谈到这篇文章的主题,也是rust绕不开的主题:所有权。

所有权模型:Rust 的所有权模型允许值在内存中有唯一的所有者

一开始我以为:引用就是其他语言(如go)里常见的引用, 而借用是更在引用之上的一种抽象,是对我们【使用引用去达到目的】这种行为的抽象 。因为我看到在一些教程里直接将两者等同混用,但其实是不对的,
因为:Rust语言中的引用和其他语言中的引用不一样,其他语言里的引用是变量的别名,Rust语言中的引用是指向某个值的指针,而不是别名。在其他语言中,引用就相当于拿到了值的别名,跟原来的值是同一个东西,可以进行任何无差别访问。在Rust语言中的借用都是临时借用使用权,并不破坏单一所有权原则。

“借用” 是指通过引用来访问值而不获取所有权; Rust 使用 “借用” 这个术语来强调在借用期间,被借用的值的仍然归原所有者所有,并且原所有者在借用期间仍然保持可变性和原始值的所有权。
就好比我从你那里借了一本书,但我肯定不能随意在上面乱写乱画,因为书还是归你所有。所以Rust的借用默认是不可变的,如果想要修改借用的值,需要显示的声明使用可变借用&mut x(取得书主人的授权)。

通过借用而不是其他语言中的直接引用,可以确保在借用期间只有一个可变或不可变的访问者,避免了悬空指针和内存安全问题。

Rust里的借用没有开辟单独的表现方式,形式上仍然是其他语言里引用的样子:在rust里,以 变量前加“&”符来表示不可变借用,例如&x ,用&mut 表示可变借用,例如:&mut x。

从能力范围上来看: 借用包含了传统意义上的引用,但是能力范围又大于引用。注意这个图只是从能力范围上来看,可变借用和传统引用好像一样,本质还是不同的,即可变借用没有获取原始变量的所有权,就好比我租了你的房子,谈好条件可以让我装修,但房子还是你的,但在我装修房子后,你再给别的租客(别的借用)来看这个房子的时候, 这个房子会是装修好后的样子。
在这里插入图片描述
借用的限制
为了保证内存安全,Rust语言中的借用也有一些限制,比如:

  • 在同一作用域中,同一数据只能有一个可变借用,即多个可变借用不能同时存在(更准确是同一所有权型变量的多个可变借用作用域不能交叠)。
  • 在同一个作用域中,同一数据可以有多个不可变借用。
  • 在一个作用域中,可变借用与不可变借用不能同时存在 (更准确是可变借用与不可变借用的作用域不能交叠)
  • 所有借用的生命周期不能超出值的生命周期(防止悬垂指针,保证内存安全)。
  • 在有借用(包括可变借用和不可变借用)存在的情况下,不能通过原所有权型变量对值进行更新。当借用完成后(借用变量的作用域结束),物归原主,才又可以使用所有权型变量对值做更新操作了。
fn main(){let mut a = 10u32;let b = &a;a = 50;println!("{b}")
}
-----------------------
fn main(){let mut a = 10u32;let b = &mut a;a = 50;println!("{b}")
}
两个例子都不能通过编译

另外有个格外的要单独说明的点:可变引用的再赋值,会执行移动操作(而不是复制),赋值后,原来那个可变引用的变量就不能用了。可以看出:一个☝️所有权型变量的可变引用也具有所有权特征。

多级可变引用

对于多级可变引用,要利用可变引用去修改目标资源值的时候,需要做正确的多级解引用操作,比如两级引用就要对应两级接引用。而且这个引用过程中必须保证全是可变引用,才可以修改到目标资源的值。

对于多级引用的,打印语句可以为我们自动接引用到正确的层数,直至访问到目标资源值。这很符合人的意图和业务需求。

在这里有个有意思的对比:

go:
func main() {var a = 10var b = &afmt.Println(a)//output:10fmt.Println(b)//output:0x... (memory address )
}
rust:
fn main() {let a = 10u32;let b = &a;let c = &&&&&&&a;println!(a)//output:10println!(b)//output:10 println!(c)//output:10 
}

可以看到rust像gpt一样识别到了我们的人类意图,没有打印的引用的内存地址,而是打印了被引用对象的值。事实上,哪怕是像let c = &&&&&&&a这种对a的多级引用,rust也仍然正确获取了a的值。

触发所有权转移的行为

会触发所有权转移的行为有:赋值操作,函数入参,函数返回值,集合操作中的移动(如Vec、HashMap等),迭代器中的移动:

先来看一个列子

fn main() {let s = String::from("rust");let s1 = s; // s的所有权转移给了s1, s不再有效// println!("{}", s); // 此处会报错,因为s已经不再有效println!("{}", s1);// s1释放
}

上面的例子中,当把s赋值给s1时,s的所有权转移到了s1,s不再有效,也就是Move语义,以确保字符串rust在同一时刻只能有一个所有者。当s1离开作用域时,s1的所有权释放,字符串rust也随之释放。
再来看下边一个:

fn main(){let  a = 10u32;let b = a;println!("{a}");// 此处不会报错,此时a和b都是有效的// a 释放println!("{b}");// b 释放
}

为什么字符串的复制会报错 而整数类型不会报错呢?

这是因为Rust对简单数据类型做了处理。假如整型、浮点型、布尔型等,这都需要转移所有权,那这程序编写起来也太复杂了吧。所以Rust语言对于这些简单数据类型,采用了Copy trait来实现,这样就是复制,而不是转移所有权。在上边的例子中因为a是简单数据类型,采用了Copy trait,所以a和b都是有效的。
实现了Copy trait的类型,在赋值或者传参时,值会自动按位拷贝;而对于没有实现Copy trait的类型,会采用Move转移所有权的方式来传递数据。

实现了Copy trait的类型:

  • 原生类型:整型(i8,u8,i16,u16,i32,u32,i64,u64,i128,u128,isize,usize)、浮点型(f32,f64)、布尔型、字符型(char)、单元类型()、Never Type(!)。
  • 不可变引用(&T)
  • 函数指针
  • 裸指针(*const T, *mut T)
  • 数组[T;N]、元组(T1, T2, …, Tn)、Option类型(需要注意的是:只有当它们的元素类型都实现了Copy trait时,它们才实现了Copy trait)。

对于复合类型,比如枚举体和结构体,Rust语言默认是不实现Copy trait的,但是如果这些类型的所有成员都实现了Copy trait,那么你可以手动添加#[derive(Copy, Clone)]来实现Copy trait。如果内部结构包含Move语义的类型,那么就无法实现Copy trait。

相关文章:

Rust核心:【所有权】相关知识点

rust在内存资源管理上采用了(先进优秀?算吗)但特立独行的设计思路:所有权。这是rust的核心,贯穿在整个rust语言的方方面面,并以此为基点来重新思考和重构软件开发体系。 涉及到的概念点:借用&am…...

单片机05__串口USART通信__按键控制向上位机传输字符串

串口USART通信 通用UART介绍 1.通信的概念 计算机与外界进行信息交换的过程称之为通信。 在通信的过程中,通信双方都需要遵守的规则称之为通信协议。 硬件协议:将数据以什么样的方式传输过去 软件协议:将数据以什么样的顺序传输过去 2.常用…...

实习日志30

概要 高拍仪硬件通信原理,WebSocket源码解析(JavaScript) WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据…...

【MySQL】探索表结构、数据类型和基本操作

表、记录、字段 数据库的E-R(entity-relationship,实体-关系)模型中有三个主要概念: 实体集 、 属性 、 关系集 。 一个实体集对应于数据库中的一个表,一个实体则对应于数据库表 中的一行,也称为一条记录。…...

解决采集时使用selenium被屏蔽的办法

解决采集时使用selenium被屏蔽的办法 实用seleniumbase uc模式 from seleniumbase import Driver driver Driver(ucTrue) # 使用UC模式UC模式是基于undetected-chromedriver 但做了一些优化更新,使用起来更方便 官方例子: from seleniumbase import …...

stream流-> 判定 + 过滤 + 收集

List<HotArticleVo> hotArticleVos hotArticleVoList .stream() .filter(x -> x.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList()); 使用Java 8中的Stream API对一个名为hotArticleVoList的列表进行过滤操作&#xff0c;筛选出符合指定条件…...

人工智能在测绘行业的应用与挑战

目录 一、背景 二、AI在测绘行业的应用方向 1. 自动化特征提取 2. 数据处理与分析 3. 无人机测绘 4. 智能导航与路径规划 5. 三维建模与可视化 6. 地理信息系统&#xff08;GIS&#xff09;智能化 三、发展前景 1. 技术融合 2. 精准测绘 3. 智慧城市建设 4. 可…...

四、分类算法 - 随机森林

目录 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结 sklearn转换器和估算器KNN算法模型选择和调优朴素贝叶斯算法决策树随机森林 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结...

pytorch -- DataLoader

定义 提供了给定数据集的迭代器 torch.utils.data.DataLoader(dataset, batch_size1, 每次拿多少数据 shuffleNone, 是否打乱 samplerNone, batch_samplerNone, num_workers0, 多进程&#xff08;加载数据时采用&#xff09;默认是0,使用主进程加载数据 collate_fnNone, p…...

【MySQL面试复习】索引创建的原则有哪些?

系列文章目录 在MySQL中&#xff0c;如何定位慢查询&#xff1f; 发现了某个SQL语句执行很慢&#xff0c;如何进行分析&#xff1f; 了解过索引吗&#xff1f;(索引的底层原理)/B 树和B树的区别是什么&#xff1f; 什么是聚簇索引&#xff08;聚集索引&#xff09;和非聚簇索引…...

四种主流的prompt框架

省流版&#xff1a; 文章介绍了在使用GPT时的四种prompt框架&#xff0c;有利于使用者打磨提问风格&#xff0c;与GPT进行更好的交互以提高生产力&#xff0c;能帮助大家有效提高工作效率~ 创作不易&#xff0c;如果对你有帮助的话&#xff0c;还请三连支持~ 想要使用Prompt…...

Educational Codeforces Round 160 (Rated for Div. 2) E. Matrix Problem(费用流)

原题链接&#xff1a;E. Matrix Problem 题目大意&#xff1a; 给出一个 n n n 行 m m m 列的 0 / 1 0/1 0/1 矩阵&#xff0c;再给出一些限制条件&#xff1a;一个长为 n n n 的数组 a a a&#xff0c;和一个长为 m m m 的数组 b b b 。 其中 a i a_{i} ai​ 表示第 …...

基于SpringBoot的气象数据监测分析大屏

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…...

关于硅的制造芯片的过程

芯片是如何制作的&#xff1f; 先将硅融化制成硅晶片&#xff0c;再用光刻机印压电路。 bilibili芯片制作视频 硅晶片作为现代芯片的主要元件&#xff0c;广泛用于集成电路。 首先将多晶硅放入特制的密封炉&#xff0c;排除其中空气后加热到1420摄氏度&#xff0c;将融化的硅放…...

【深度学习笔记】3_10 多层感知机的PyTorch实现

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.10 多层感知机的简洁实现 下面我们使用PyTorch来实现上一节中的多层感知机。首先导入所需的包或模块。 import torch from torch import nn from torch.nn import …...

输入法在 Android13上候选词 候选区域 不显示的问题

背景 自研的输入法发现在 Android13 平台上不显示候选区域&#xff0c;在之前平台上以及需求是输入英文时不显示&#xff0c;中文需要显示。 最终解决办法&#xff1a;setExtractViewShown(false) Override public View onCreateCandidatesView() {...setExtractViewShown(f…...

Java 面向对象进阶 18 JDK8、9开始新增的方法;接口的应用;适配器设计模式;内部类(黑马)

一、JDK8开始新增的方法 默认方法不是抽象方法&#xff0c;所以不强制被重写&#xff1a; 但是如果被重写&#xff0c;就要去掉default关键字&#xff1a; public可以省略&#xff0c;但是default不可以省略&#xff1a; public是灰色的&#xff0c;代表可以省略 但是default是…...

数据结构-二分搜索树(Binary Search Tree)

一,简单了解二分搜索树 树结构: 问题:为什么要创造这种数据结构 1,树结构本身是一种天然的组织结构,就好像我们的文件夹一样,一层一层的. 2,树结构可以更高效的处理问题 二,二分搜索树的基础 1、二叉树 2,二叉树的重要特性 满二叉树 总结: 1. 叶子结点出现在二叉树的最…...

YOLO如何训练自己的模型

目录 步骤 一、打标签 二、数据集 三、跑train代码出模型 四、跑detect代码出结果 五、详细操作 步骤 一、打标签 &#xff08;1&#xff09;在终端 pip install labelimg &#xff08;2&#xff09;在终端输入labelimg打开 如何打标签&#xff1a; 推荐文章&#xf…...

05 EXTI外部中断

一、中断系统 中断系统&#xff1a;管理和执行中断的逻辑结构。中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件——中断源&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...