【rust】| 06——语言特性 | 所有权

系列文章目录
【rust】| 00——开发环境搭建
【rust】| 01——编译并运行第一个rust程序
【rust】| 02——语法基础 | 变量(不可变?)和常量
【rust】| 03——语法基础 | 数据类型
【rust】| 04——语法基础 | 函数
【rust】| 05——语法基础 | 流程控制
【rust】| 06——语言特性 | 所有权

文章目录

  • 1. 所有权的概念
  • 2. 所有权的规则
  • 3. 变量的作用域
  • 4. 所有权的移动/克隆
    • 4.1 移动
    • 4.2 克隆 clone
    • 4.3 copy
  • 5. 所有权的转移
    • 5.1 函数转移
    • 5.2 返回值转移
  • 6. 引用和借用
    • 6.1 引用
    • 6.2 借用
    • 6.3 可变引用
    • 6.4 空引用
  • 7. 切片
    • 7.1 字符串切片
    • 7.2 其他切片
    • 7.3 切片的范围
    • 7.4 切片做函数参数

1. 所有权的概念

 所有权是Rust语言中一个关键的特性。它是一种内存管理规则(机制)。它通过这个规则(即所有权系统)结合编译器对代码进行检查 从而确保内存安全。
 在其他语言如C/C++ 等 都有自己的内存管理方式。C/C++需要我们显式(手动)处理所用的内存(申请、释放) 如果处理不当会造成很严重的内存安全问题。而Rust中这一特性很好的可以帮我们确保内存安全性。

2. 所有权的规则

1、每个值都对应一个变量 owner
2、一个值只能有一个 owner
3、有作用域,当owner超出作用域 值会被销毁 (这个变量有生命周期 在作用域内)

3. 变量的作用域

Rust中变量的作用域和其他语言类型。比如函数体内的 变量(局部变量) 它的作用域在 函数大括号之间 生命周期也是这么短。
在这里插入图片描述
可以看到 超过范围销毁了。 对应所有权规则的最后一条。owner 就是这个值藏在暗处的变量名。 它超过变量作用域会消失。Rust内部在超出后 会掉清理函数 drop
清理变量占用的内存。

4. 所有权的移动/克隆

4.1 移动

Rust中的移动 类似浅拷贝 但有细节之处。
我们通过代码例子去理解

1、变量赋值操作

在这里插入图片描述
分析:
  1、整型变量赋值 变量a 复制到了 变量b
  2、字符串赋值 变量s1 复制到了 变量s2
  我们可以看到 两种不同的类型 操作几乎是一样的。 整型它只是一个数字 再怎么复制占用的大小就那么多 无关紧要。可是当是一个很大的字符串 复制给另一个变量 那所占用的大小(很大*2) 这样的操作 太占用大小 咋的一个字符串准备要我命啊。是不是和其他语言复制操作很类似。
  但是在 Rust中 复制的操作 还是有细微差别的 我们深入了解下rust下 具体复制的具体过程

细看 字符串变量的定义及复制到其他变量的过程

在这里插入图片描述
可以看到 字符串变量的内容 hello 存储在堆上 而 定义的变量 S1 只保存了 指向堆上内容的指针、长度和容量这三个 这些内容存储在栈上。并没有将 字符串内容也保存。
下面我们看 S1内容复制给S2 是怎样的
在这里插入图片描述
可以看到 S1 复制到 S2 也只是复制了 指针、长度、容量三件套。不重复复制堆上内容。这样的情况下S1 S2是不是 占用栈大小很少。

如果S1 S2把数据一起保存呢
在这里插入图片描述
可以看到 全保存过来 每个变量 都这样完全复制 那栈吃不消。当内容很大时 是不是 一个赋值操作直接给 栈空间 用完 干废掉啦。

通过上面图我们可以看到 rust中 变量保存了指向内容的指针等。 S1 和S2 中的指针都指向了 数据内容。我们知道所有权规则之一 变量超出作用域 会没了。那么当S1和S2 超出作用域 会尝试释放 因为它两指向一个地址那么 两次释放是不是会出大问题呢。也称为 双重释放错误。
当然 rust中也会想到这种错误 所以它会避免啦。
在这里插入图片描述

在这里插入图片描述
在Rust中 执行完 S2=S1这样的操作 S1已经变得无效啦 所以不会再存在上面双重释放的隐患了。
其实 Rust中S2 = S1 的操作类似浅拷贝 只拷贝了指针长度容量。但是rust 中超出范围 让其消失的规则 即S1 无效啦的操作 我们把这样称为 移动

4.2 克隆 clone

Rust中 我们把类似 深拷贝(把数据内容一起复制)的操作
称为克隆 clone。
在这里插入图片描述

4.3 copy

前面学习完 移动和克隆 我们理解到 在Rust中 通过变量给变量赋值的操作 如果直接赋值 S2 = S1 这种 类似于浅拷贝 而且S1会消失 没有拷贝在堆上的内容 而 通过克隆 s2=s1.clone() 这种 类似深拷贝的操作 这样S1还活着。 下面我们通过例子理解COPY
在这里插入图片描述
为什么x 还能用? 因为X是整型 编译器编译时 知道它的大小 将内容全部存储在栈中。也可以说整型具有copy特性 所以才会存在栈上。字符串型 大小我们不确定因为不知道后面会不会 改变。 在这种情况下 深浅拷贝(克隆)没区别。

具有copy特性的类型

  • 所以整型
  • 布尔类型
  • 所以浮点型
  • 字符型 char
  • 元组(元素类型为以上几种)

5. 所有权的转移

函数和返回值 都可以转移属性

5.1 函数转移

通过函数入参 将变量移动/复制 和变量移动/复制一样的
通过例子学习

在这里插入图片描述
通过这个可以看到 和变量是一样的

5.2 返回值转移

通过返回值 转移

在这里插入图片描述

6. 引用和借用

有些场景我们只需要使用值 而且会多次使用 一个变量本身具有所有权 多次使用需要移动来移动去 好麻烦 有没有办法不要所有权 那就是通过引用的方式。

6.1 引用

引用: 使用值而不转移(获取)所有权
引用没有所有权

引用通过地址来访问存储在该地址的数据

在这里插入图片描述
在这里插入图片描述
我们可以看到上面 函数定义入参 s: &sring 它的含义 我们创建了一个引用 来接收传入的实参引用 也称为 借用

6.2 借用

借用 是创建引用的动作
借用是 不能修改引用的值

借用 顾名思义 我借了别人东西 我要原模原样还给人家 不能说 搞坏了还吧
上demo
在这里插入图片描述

可以看到 引用 和 默认情况下的变量 一样是不可变的

6.3 可变引用

引用默认情况下 不可修改内容 和默认变量一样

上面代码因为我们定义了不可变的变量等 那我们给他给加上可变的标志 是不是就可以变啦 是的

在这里插入图片描述
可以看到 定义变量 函数入参等 都修改为 可变的 少一个都不行 否者会报错 既然要该那么都得是可变属性哦

可变引用的约束

1、一个变量只能有一个可变引用

防止多个引用同时对一个值 修改

在这里插入图片描述

6.4 空引用

类似空指针。
在rust中 编译器会保证不会存在空引用。
编译器检测过程
在这里插入图片描述
但我们又想用 函数内局部变量怎么办
前面我们学习了 返回值可以转移所有权 那么我们返回 变量是不是就可以了
在这里插入图片描述

7. 切片

切片也是一种引用,切片没有所有权。
切片:对一个集合(元组 字符串) 引用其部分连续元素的操作
注: 切片不能对整个切 只能连续的某部分 是有范围的

7.1 字符串切片

在这里插入图片描述
我们看看切片数据的内部存储结构是怎样的
在这里插入图片描述
可以看到切片只存储了 起始位置的指针 和切的长度

还有一种字符串类型 &str 它指向二进制文件 这个字符串不可变
let s=“awdada”; // s是 &str类型

7.2 其他切片

和字符串切片类似 只是切的对象换了 可以切好多
比如 切数组 引用数组中一部分元素
在这里插入图片描述

7.3 切片的范围

我们通过前面知道切片是如何创建
知道了 [ ] 方括号之间需要填切片的范围
那么当我们想切片的起始位置从0开始 除了 [0…x] 还有其他的表达方式

1、切片索引从0开始 的表达方式

在这里插入图片描述

同样的 结尾位置 也可以 用省略 表达

2、切片索引 到末尾 的表达方式

在这里插入图片描述

3、表示整个 同理 省略起始和结尾值 [ . . ]

7.4 切片做函数参数

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国货大佬“卡脖子”后王者风范不减?小米卷出光学拍摄“天花板”?| 手机行业社媒心智品牌榜出炉

Social Power 核心解读 1、智能手机“乍暖还寒”,龙头品牌仍稳占消费者心智 比拼屏幕、赶超系统、迭代形态、拓展概念?眼花缭乱过后,产品精益求精,建立稳固的消费者认知,才是“保鲜”关键。在最新发布的数说故事5月…

MyBatis Plus 拦截器实现数据权限控制

一、介绍 上篇文章介绍的MyBatis Plus 插件实际上就是用拦截器实现的,MyBatis Plus拦截器对MyBatis的拦截器进行了包装处理,操作起来更加方便 二、自定义拦截器 2.1、InnerInterceptor MyBatis Plus提供的InnerInterceptor接口提供了如下方法&#x…

基于AI技术的API开发工具,自动化和智能化快速高效开发API

一、开源项目简介 ApiCat 是一款基于 AI 技术的 API 开发工具,它旨在通过自动化和智能化的方式,帮助开发人员更快速、更高效地开发 API。ApiCat 支持 OpenAPI 和 Swagger 的数据文件导入和导出,并可以对用户输入的 API 需求进行分析和识别&a…

真题详解(补码转换)-软件设计(七十四)

真题详解(索引查询)-软件设计(七十三)https://blog.csdn.net/ke1ying/article/details/130659024 Composite模式: 以树形结构来表示”整体-部分”的关系,使得单个和团体的使用都具有一致性。 对一个基本有序的数组进行排序,适合…

精彩回顾 | Fortinet Accelerate 2023·中国区巡展厦门站

Fortinet Accelerate 2023中国区 5月16日,Fortinet Accelerate 2023中国区巡展来到魅力“鹭岛”——厦门,技术、产品和业务专家,携手亚马逊云科技、唯一网络等云、网、安合作伙伴,与交通、物流、金融等各行业典型代表客户&#x…

HR真的会嫌弃跳槽频繁的测试人员吗?

我们都知道:“跳槽≠涨薪”,但是对于测试人来说,跳槽绝哔能和升职加薪画上等号啊。 所以,有很多测试人在一家公司常常待不到1年,就另觅新东家,来借此达成升职加薪的目的。 有人提出质疑:为什么测…

嚯——ChatGPT是很强,但也会胡说八道。。。

现在的ChatGPT确实强,但是也会一本正经的胡说八道,例如它回答“nineteen”中有12个字母、或是旗鱼是哺乳动物…… 尽管ChatGPT可以生成流畅甚至优雅的散文,轻松通过困扰了AI领域超过70年的图灵测试基准,但它也可能看起来非常愚蠢…

探讨接口测试颗粒度

偶然间在论坛上看到一个帖子,帖子内容如下: 假设现在有一个新增商品的接口,返回的参数中有新增商品的 id(每次返回的 id 都不一样)、success(判断是否成功,0 失败 1 成功) 1. 接口…

Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本)

Elasticsearch painless脚本 1.什么是painless2.painless的特性3.使用kibana进行准备操作3.1 使用kibana创建索引和映射3.2 使用kibana添加测试数据 4.使用painless执行查询操作关于脚本查询须知4.1 字段查询脚本4.1 排序查询脚本 5.如何使用painless执行更新操作关于脚本查询须…

【机器学习】第二节:线性回归和线性分类

作者🕵️‍♂️:让机器理解语言か 专栏🎇:机器学习sklearn 描述🎨:本专栏主要分享博主学习机器学习的笔记和一些心得体会。 寄语💓:🐾没有白走的路,每一步都算…

Text-to-SQL提示工程【Prompt Engineering】

我们刚刚启动了一个开源项目pg-text-query,目标是为文本到 SQL 制作生产就绪的大型语言模型 (LLM) 提示。 我们的目标是 利用 LLM、我们自己对 PostgreSQL 数据库的深入了解以及严格的测试来开发一流的文本到 SQL 的翻译。 推荐:用 NSDT设计器 快速搭建…

【MySQL】C语言连接数据库

在使用数据库的时候&#xff0c;我们是操作客户端方的&#xff0c;向服务器请求数据。MySQL的端口号-3306 连接mysql需要头文件&#xff1a;#include<mysql/mysql.h> 基础连接步骤&#xff1a; 1.创建连接句柄 MYSQL mysql_con;//连接句柄 2.初始化连接句柄mysql_i…

「OceanBase 4.1 体验」|大厂开始接入的国产分布式数据库,不来了解了解?

OceanBase 4.1 体验 前言OCP Express在线升级功能租户级物理备库TP&#xff08;事务处理&#xff09;和AP&#xff08;分析处理&#xff09;优化TP 性能优化AP 性能优化 结尾 前言 上次我们讲了本人自己亲自上手OceanBase 4.1的初体验&#xff0c;国产的分布式数据库也太太太太…

有哪些好用的AI工具?

现在有很多好用的AI工具&#xff0c;以下是一些常用的&#xff1a; 1. TensorFlow&#xff1a;谷歌开发的深度学习框架&#xff0c;支持多种编程语言&#xff0c;包括Python、C、Java等。 2. PyTorch&#xff1a;Facebook开发的深度学习框架&#xff0c;易于使用&#xff0c;…

Redis源码分析之网络模型

Redis网络模型 阅读源码的初衷Redis源码阅读 阅读源码的初衷 很多网上解释这个Redis为啥这么块&#xff1f;都会说Redis这么快的原因会有一个Redis才用了单线程&使用了多路io复用来检查io事件&#xff0c;单线程可以避免多线程对资源的竞争。如果我们使用了多线程那么就需…

ChatGPT其实并不想让开发人员做这5件事情

前言 ChatGPT已经火爆了快半年了吧&#xff0c;紧接着国内也开始推出了各种仿制品&#xff0c;我甚至一度怀疑&#xff0c;如果人家没有推出ChatGPT&#xff0c;这些仿制品会不会出现。而很多人也嗨皮得不行&#xff0c;利用各种方法开始科学上网&#xff0c;用ChatGPT做各种觉…

[读书笔记] Variational AutoEncoders

小全读书笔记 《Variational AutoEncoders》 1. Generative Model &#xff08;生成式模型&#xff09;简述2. 简单生成模型 AutoEncoders2.1 结构2.2 不足 3. Variational AutoEncoders4. Variational AutoEncoders的数学支持 此读书笔记来自于Joseph Rocca的Understanding Va…

APP 兼容性测试是什么?8年测试老鸟告诉你

1、APP 兼容性测试认识 随着 APP 应用范围越来越广&#xff0c;用户群体越来越大&#xff0c;终端设备的型号也越来越多&#xff0c;移动终端碎片化加剧&#xff0c;使得 APP 兼容性测试成为测试质量保障必须要考虑的环节。 APP 兼容性测试通常会考虑&#xff1a;操作系统、厂…

js执行思维导图

备注&#xff1a; js执行&#xff1a; 执行分为两部分&#xff1a;预执行和执行 预执行&#xff1a;创建好执行上下文 执行&#xff1a;执行栈中执行 js引擎&#xff1a; 读取并执行js 各个浏览器的引擎如下 …

linux学习[10]磁盘与文件系统(1):查看磁盘容量指令df 评估文件系统的磁盘使用量指令 du

文章目录 前言1. df指令2. du指令 前言 TF卡制作的过程中涉及到了磁盘分区格式化等问题&#xff0c;当时对具体的指令理解不是特别深刻&#xff1b;由此引申到我对linux中的整个磁盘与文件系统没有一个全面的认识&#xff0c;这个磁盘与文件系统的系列博客章节就对这些进行记录…