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等),迭代器中的移动:

todo 补充copy trait的有关内容

Rust语言中,对于实现了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。

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

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

相关文章

[更新]ARCGIS之土地耕地占补平衡、进出平衡系统报备坐标txt格式批量导出工具(定制开发版)

序言 之前开发的耕地占补平衡报备格式,现在之前的基础上集成了耕地进出平衡报备格式导出。 之前版本软件详见:软件介绍 一、软件简介 本软件是基于arcgis二次开发的工具(插件),需要授权后才能使用; 本软件…

Java设计模式 | 简介

设计模式的重要性: 软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。 这个术语由埃里希 伽玛(Erich Gamma)等人在1…

FairyGUI × Cocos Creator 3.x 场景切换

前言 前文提要: FariyGUI Cocos Creator 入门 FairyGUI Cocos Creator 3.x 使用方式 个人demo:https://gitcode.net/qq_36286039/fgui_cocos_demo_dust 个人demo可能会更新其他代码,还请读者阅读本文内容,自行理解并实现。 官…

AD24-蛇形走线

一、单端蛇形走线 1、公差参数 2、布线-网络等长调节 3、参数说明 ①手工输入绕线的长度 ②参照个网络的长度绕线 ③按照自身设置的规绕线(一般选用) 4、调节 5、最后 二、差分蛇形走线 1、布线-差分对网络等长调节 2、如在选中的时候出现问题,按CtrlD…

Stable Diffusion 绘画入门教程(webui)-ControlNet(IP2P)

上篇文章介绍了深度Depth,这篇文章介绍下IP2P(InstructP2P), 通俗理解就是图生图,给原有图加一些效果,比如下图,左边为原图,右边为增加了效果的图: 文章目录 一、选大模型二、写提示词三、基础参…

大模型分布式训练方法FDSP和DeepSpeed

备注: 本文部分内容参考自其他作者的内容,如有不妥,请联系,立即删除。 pytorch单精度、半精度、混合精度、单卡、多卡(DP / DDP)、FSDP、DeepSpeed模型训练 相关代码:pytorch-model-train-temp…

python 打包 apk

转换之前python代码需要使用指定的框架才能转换,列如:kivy from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Buttonimport time import pyautogui import threadingstatus False# 这是一个将被线程执…

【Vue渗透】Vue Devtools 浏览器插件

下载地址 Vue Devtools 浏览器插件 Vue站点渗透思路 【Vue渗透】Vue站点渗透思路 简介 Vue Devtools 是 Vue 官方发布的调试浏览器插件,可以安装在 Chrome 和 Firefox 等浏览器上,直接内嵌在开发者工具中,使用体验流畅。Vue Devtools 由…

模型 金字塔原理

系列文章 分享 模型,了解更多👉 模型_总纲目录。清晰逻辑,有效沟通。 1 金字塔原理的应用 1.1 应用金字塔原理提出一个新产品的市场推广策略 确认结论:我们应该采取在线社交媒体广告和口碑营销的策略来推广新产品。 构建层级1&…

在Ubuntu系统下搭建TDengine集群

目录 一、Ubuntu虚拟机创建 二、系统相关配置 1、设置系统hostname 2、网络配置及IP规划 3、配置FQDN(etc/hosts) 4、服务端口设置 三、TDengine server安装 1、服务安装 2、修改配置 3、启动taosd 4、服务卸载 四、客户端安装 1、client安…

cookie伪造 [BSidesCF 2019]Kookie1

打开题目 提示用admin用户登录 尝试弱口令发现,登录失败 显示用admin&passwordadmin!进行登录 有发现说cookie,就尝试用cookie登录: f12编辑添加cookie重发包: 或者bp抓包 Cookie:usernameadmin 用admin登录成功 得到flag: 参考文章&…

基于SVM的功率分类,基于支持向量机SVM的功率分类识别,Libsvm工具箱详解

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 完整代码和数据下载链接:基于SVM的功率分类,基于支持向量机SVM的功率分类识别资源-CSDN文库 https://download.csdn.net/download/abc991835105/88862836 SVM应用实例, 基于…