【Rust中级教程】1.10. 引用及内部可变性(简单回顾):引用、内部可变性、`Cell`类型及相关操作
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
这篇文章只对所有权进行简单回顾,想要看完整的所有权系统阐述见【Rust自学】专栏的第15章的文章。

1.10.1. 引用
通过引用,Rust允许将值借用出去,但不放弃所有权。
引用就是带有附加合约的指针。Rust中一共有两种引用类型。
1. 共享的引用
共享的引用,又叫不可变的引用,Rust中写作&T,其中T指代类型。
它的特点在一可以同时(或者叫在同一作用域内)存在任意数量的引用指向同一个值。每个共享的引用都实现了Copy trait。
共享引用背后的值不可变。编译器允许假定共享引用指向的值,在该引用存货期间是不会改变的。
举个例子:一个共享引用的值在某函数内被多次读取,那编译器就有权让其只读取一次,然后重用读取的值。
2. 可变引用
与不可变引用相对的就是可变引用,在Rust中写作&mut T。
可变引用是独占的,意味着在一个作用域内只能有一个可变引用,不能出现第二个可变引用或任意数量的共享引用。所以不可变引用没有实现Copy trait。
编译器会假定没有其它线程访问可变引用所指向的类型(无论是通过共享引用还是可变引用)。
1.10.2. 拥有值 vs. 拥有到值的可变引用
所有者需要对删除值(丢弃值)负责,除此之外两者的作用基本一样。
注意:如果你移动了可变引用背后的值,则必须在其位置上留下另一个值。如果不这样做,所有者会认为它需要将其删除(丢弃),但其实却没有值可以删除了,导致未定义行为或编译错误。
看个例子:
fn main() {let mut s = String::from("Hello");let r = &mut s;let t = *r; // 试图移动 r 所指向的值println!("{}", r); // r 变成了悬垂引用
}
输出:
error[E0507]: cannot move out of `*r` which is behind a mutable reference
我们来梳理一下过程:
r是s的可变引用,而*r的操作试图移动这个值(String类型没有实现Copytrait,意味着s会失去数据)- 由于
s仍然存在,当s作用域结束时,Rust期望可以正常释放它的内存 - 但
s已经被移动走了,导致Rust不知道该如何正确释放它,从而引发编译错误
正确的做法:
fn main() {let mut s = String::from("Hello");let r = &mut s;let t = std::mem::replace(r, String::new()); // 用空字符串替换原值println!("{}", t); // "Hello"println!("{}", s); // ""
}
1.10.3. 内部可变性
一些类型提供了内部可变性,这些类型可以通过共享引用修改值。
这些类型通常依赖于额外的机制(如原子CPU指令)或不变量来提供安全的可变形,而不依赖于独占引用的语义。
内部可变性分为两类:
-
通过共享引用获得可变引用:
Mutex、RefCell(这两者在【Rust自学】专栏的第15章的文章中都介绍过)
这类类型提供了保障机制——如果对某个值提供了可变引用,那么同时(或者叫在同一作用域下)只会存在一个可变引用,并且没有共享引用。这种功能依赖于UnsafeCell类型,通过共享引用修改值的唯一正确方式。 -
通过共享引用可以替换值:
std::sync::atomic、std::cell::Cell
这类类型没有提供可变引用到内部的值,但是提供了就地操作值的方法——比如说替换/读取一个值。例如:无法获得到usize或i32的直接引用,但是可以读取和替换值。
1.10.4. Cell类型
Cell类型来自于标准库,它通过不变量实现内部可变性。
Cell类型无法跨线程共享,因为内部值不会被并发地修改,即使通过共享引用发生修改- 不会提供到
Cell内部的值的引用(所以可以一直移动它)
Cell提供的方法:
- 对值整体替换(也就是所谓的就地操作)
- 返回值的副本(也就是读取)
1. set(value): 替换值
use std::cell::Cell;fn main() {let x = Cell::new(10); // 创建一个 `Cell`,存储 10x.set(20); // 替换内部值println!("Updated value: {}", x.get()); // 输出 20
}
set(value)用新值替换Cell内部的值
2. get():返回值的副本
use std::cell::Cell;fn main() {let x = Cell::new(5);let y = x.get(); // 获取 `x` 内部的副本println!("Value: {}", y); // 输出 5
}
get()不会返回内部值的引用,而是返回值的副本(适用于实现Copytrait 的类型)。- 适用于
i32、bool等实现Copytrait 的类型。
相关文章:
【Rust中级教程】1.10. 引用及内部可变性(简单回顾):引用、内部可变性、`Cell`类型及相关操作
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 这篇文章只对所有权进行简单回顾,想要看完整的所有权系统阐述见【Rust自学】专栏…...
Docker 安装和配置 Nginx 详细图文教程
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template 🌺 仓库主页: GitCode︱ Gitee ︱ Github 💖 欢迎点赞 👍 收藏 ⭐评论 …...
基于Java+Swing+Mysql实现旅游管理信息系统
基于JavaSwingMysql实现旅游管理信息系统 一、系统介绍二、功能展示1.登陆2.注册3.旅游信息查询4.查看游行团信息5.报名6、报名信息管理 三、数据库四、其它1.其他系统实现五.获取源码 一、系统介绍 用户:登陆、注册、旅游信息查询、查看游行团信息、报名 管理员&a…...
使用 Openpyxl 操作 Excel 文件详解
文章目录 安装安装Python3安装 openpyxl 基础操作1. 引入2. 创建工作簿和工作表3. 写入数据4. 保存工作簿5. 加载已存在的Excel6. 读取单元格的值7. 选择工作表 样式和格式化1. 引入2. 设置字体3. 设置边框4. 填充5. 设置数字格式6. 数据验证7. 公式操作 性能优化1. read_only/…...
统信服务器操作系统V20 1070A 安装docker新版本26.1.4
应用场景: 硬件/整机信息:x86平台、深信服超融合平台 OS版本信息:统信V20 1070a 1.获取docker二进制包 链接: https://pan.baidu.com/s/1SukBlra0mQxvslTfFakzGw?pwd5s5y 提取码: 5s5y tar xvf docker-26.1.4.tgz groupadd docker ch…...
【数据分享】1929-2024年全球站点的逐年降雪深度数据(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2024年全球气象站…...
python爬虫系列课程1:初识爬虫
python爬虫系列课程1:初识爬虫 一、爬虫的概念二、通用爬虫和自定义爬虫的区别三、开发语言四、爬虫流程一、爬虫的概念 网络爬虫(又被称为网页蜘蛛、网络机器人)就是模拟浏览器发送网络请求,接收请求响应,一种按照一定的规则,自动抓取互联网信息的程序。原则上,只要是…...
大模型工具大比拼:SGLang、Ollama、VLLM、LLaMA.cpp 如何选择?
简介:在人工智能飞速发展的今天,大模型已经成为推动技术革新的核心力量。无论是智能客服、内容创作,还是科研辅助、代码生成,大模型的身影无处不在。然而,面对市场上琳琅满目的工具,如何挑选最适合自己的那…...
什么是语料清洗、预训练、指令微调、强化学习、内容安全; 什么是megatron,deepspeed,vllm推理加速框架
什么是语料清洗、预训练、指令微调、强化学习、内容安全 目录 什么是语料清洗、预训练、指令微调、强化学习、内容安全语料清洗预训练指令微调强化学习内容安全什么是megatron,deepspeed,vllm推理加速框架语料清洗 语料清洗是对原始文本数据进行处理的过程,旨在去除数据中的…...
HTTP的“对话”逻辑:请求与响应如何构建数据桥梁?
一、前言 作为现代互联网通信的基石,HTTP协议定义了客户端与服务器之间的“对话规则”。每一次网页加载、API调用或文件传输的背后,都离不开精心构造的HTTP请求与响应。请求中封装了用户的意图——从请求方法、资源路径到提交的数据;响应则承…...
【深度学习】预训练和微调概述
预训练和微调概述 1. 预训练和微调的介绍1.1 预训练(Pretraining)1.2 微调(Fine-Tuning) 2. 预训练和微调的区别 预训练和微调是现代深度学习模型训练中的两个关键步骤,它们通常是一个 预训练-微调 (Pretrain-Finetune…...
自动化测试框架搭建-单次接口执行-三部曲
目的 判断接口返回值和提前设置的预期是否一致,从而判断本次测试是否通过 代码步骤设计 第一步:前端调用后端已经写好的POST接口,并传递参数 第二步:后端接收到参数,组装并请求指定接口,保存返回 第三…...
【阮一峰】2.数组
数组 简介 所有成员的类型必须相同,但是成员数量是不确定的。 由于成员数量可以动态变化,所以 TypeScript 不会对数组边界进行检查,越界访问数组并不会报错。 第一种写法: let arr: (number | string)[];第二种写法ÿ…...
DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方DeepSeek接入)
前言 在当今数字化时代,AI编程助手已成为提升开发效率的利器。DeepSeek作为一款强大的AI模型,凭借其出色的性能和开源免费的优势,成为许多开发者的首选。今天,就让我们一起探索如何将DeepSeek接入PyCharm,实现高效、智…...
【Java Card】Applet 使用Shareable进行数据分享以及部分问题处理
文章目录 前言一、定义接口二、server端实现三、client端实现四、遇到的问题 前言 在进行开发时,可能会将业务放到不同的applet中,这时常常会需要进行数据的分享。 比如在一个applet中存储了密钥,而在另一个业务applet中需要进行签名时&…...
国产FPGA开发板选择
FPGA开发板是学习和开发FPGA的重要工具,选择合适的开发板对学习效果和开发效率至关重要。随着国产FPGA的发展,淘宝上的许多FPGA开发板店铺也开始进行国产FPGA的设计和销售,本文将对国产FPGA和相关店铺做个简单梳理,帮助有需要使用…...
com.typesafe.config
com.typesafe.config 是 Typesafe Config 库的核心包,主要用于 统一、灵活地管理应用程序配置,支持从多种格式(如 HOCON、JSON、Java Properties)加载配置,并提供类型安全的访问接口。以下是其核心功能的详细解析&…...
Ubuntu学习备忘
1. 打开Terminal快捷键 ctrl alt t 2.Ubuntu22.04的root没有默认初始密码, 为root设置密码,下面链接的step1, How to allow GUI root login on Ubuntu 22.04 Jammy Jellyfish Linux - LinuxConfig...
【C++】— 掌握STL vector 类:“Vector简介:动态数组的高效应用”
文章目录 1.vector的介绍和使用1.1vector的介绍1.2 vector的特点1.3vector的使用1.3.1vector的定义1.3.2vector iterator的使用1.3.3vector 的空间增长问题1.3.4 vector 的增删查改1.3.5vector 迭代器失效问题 1.vector的介绍和使用 1.1vector的介绍 vector是一个顺序容器&am…...
Docker__持续更新......
Docker 1. 基本知识1.1 为什么有Docker?1.2 Docker架构与容器化 画图解释 画图解释2. 项目实战 1. 基本知识 1.1 为什么有Docker? 用一行命令跨平台安装项目,在不同平台上运行项目。把项目打包分享运行应用。 1.2 Docker架构与容器化 准备机器,在机…...
很多人不知道:AI证书还有隐藏费用
AI风口下,“持证上岗”“证书职场加分项”的宣传较为常见,不少人希望借助考证提升自身竞争力。但部分人只关注表面的报名费,忽略了背后可能存在的隐形费用,等到陆续掏钱时才发现,实际花费远超预期,所谓的“…...
GD32F4xx时钟树避坑指南:HXTAL选8M还是25M?AHB分频怎么设性能最优?
GD32F4xx时钟树实战解析:晶振选型与总线分频的黄金法则 在嵌入式系统设计中,时钟配置往往是最容易被低估的关键环节。当我在去年负责一个工业网关项目时,曾因为草率选择了25MHz外部晶振而遭遇产品批量返修的惨痛教训——在高温环境下…...
终极游戏模组加载器:3分钟学会安装任何游戏插件
终极游戏模组加载器:3分钟学会安装任何游戏插件 【免费下载链接】Ultimate-ASI-Loader The Ultimate ASI Loader is a proxy DLL that loads custom .asi libraries into any game process. 项目地址: https://gitcode.com/gh_mirrors/ul/Ultimate-ASI-Loader …...
别再只用border-radius了!用CSS radial-gradient实现Chrome标签页同款反向圆角
突破CSS边界:用radial-gradient打造高级反向圆角设计 在网页设计的细节美学中,圆角处理早已成为提升界面亲和力的标配。但当我们把目光转向Chrome浏览器标签页那种精致的反向圆角效果时,传统的border-radius就显得力不从心了。这种看似简单的…...
别再死记硬背公式了!用Python代码实战拆解Diffusion中的两种引导技术(附避坑指南)
用Python实战拆解Diffusion模型中的两种引导技术:从代码理解原理到避坑指南 当你第一次看到"Classifier Guidance"和"Classifier-Free Guidance"这两个术语时,是否也被那些复杂的数学公式和理论推导搞得头晕目眩?作为一位…...
为什么说MoeKoeMusic是二次元音乐爱好者的终极播放器?揭秘这款开源酷狗客户端的完整使用指南
为什么说MoeKoeMusic是二次元音乐爱好者的终极播放器?揭秘这款开源酷狗客户端的完整使用指南 【免费下载链接】MoeKoeMusic 一款开源简洁高颜值的酷狗第三方客户端 An open-source, concise, and aesthetically pleasing third-party client for KuGou that support…...
告别C盘红色警告!把WSL 2的虚拟硬盘迁移并扩容到其他盘(D/E盘教程)
彻底解放C盘空间:WSL 2虚拟硬盘迁移与智能扩容全攻略 每次打开Windows资源管理器,那个刺眼的红色警告条总让人心头一紧——C盘又满了。对于深度使用WSL 2的开发者和数据科学工作者来说,这个问题尤为棘手。默认安装在C盘的WSL 2虚拟硬盘(VHDX)…...
ADB复杂命令拆解
1、获取包名方法一:最简单直接(手机正在运行该 App)adb shell dumpsys window | findstr mCurrentFocus快速查看当前手机屏幕上,到底是哪个 App 的哪个页面(Activity)正处于显示状态。adb shell:…...
华硕笔记本性能优化神器:G-Helper终极使用指南与技巧大全
华硕笔记本性能优化神器:G-Helper终极使用指南与技巧大全 【免费下载链接】g-helper The control app every laptop should come with. G-Helper is a fast, native tool for tuning performance, fans, GPU, battery, and RGB on any Asus laptop or handheld - RO…...
05华夏之光永存・开源:黄大年茶思屋榜文解法「23期 5题」 【分布式收发机设计专项完整解法】
05华夏之光永存・开源:黄大年茶思屋榜文解法「23期 5题」 【分布式收发机设计专项完整解法】 一、摘要 分布式收发机设计与低秩/稀疏优化赛道,全球现代工程技术已触达绝对性能天花板。传统集中式均衡、单模块预编码、固定流量分配的技术框架,…...
