rust中的reborrow和NLL
reborrow
我们看下面这段代码
fn main() {let mut num = 123;let ref1 = &mut num; // 可变引用add(ref1); // 传递给 add 函数println!("{}", ref1); // 再次使用ref1
}fn add(num: &mut i32) {println!("{}", *num);
}
我们知道可变引用是没有实现Copy trait的,因此,当ref1传递给add函数之后,其所有权应该被转移到add函数内,之后应该无法使用ref1,但是上面这段代码是可以编译,运行的。这是为什么呢?
经过辛苦的寻找,在github上找到了相关的pull request以及rust核心开发者nikomatsakis在这篇文档中提到的reborrow。原文如下:
One of the less obvious but more important coercions is what I call
*reborrowing*, though it's really a special case of autoborrow. The
idea here is that when we see a parameter of type `&'a T` or `&'a mut
T` we always "reborrow" it, effectively converting to `&'b T` or `&'b
mut T`. While both are borrowed pointers, the reborrowed version has
a different (generally shorter) lifetime. Let me give an example where
this becomes important:fn update(x: &mut int) {*x += 1;}fn update_twice(x: &mut int) {update(x);update(x);}In fact, thanks to auto-borrowing, the second function is implicitly
transformed to:fn update_twice(x: &mut int) {update(&mut *x);update(&mut *x);}This is needed because `&mut` pointers are *affine*, meaning that
otherwise the first call to `update(x)` would move the pointer `x`
into the callee, leading to an error during the second call. The
reborrowing however means that we are in fact not moving `x` but
rather a temporary pointer (let's call it `y`). So long as `y` exists,
access to `x` is disabled, so this is very similar to giving `x` away.
However, lifetime inference will find that the lifetime of this
temporary pointer `y` is limited to the first call to `update` itself,
and so after the call access to `x` will be restored. The borrow
checker rules permit reborrowing under the same conditions in which a
move would be allowed, so this transformation never introduces errors.
对应的译文(来自chatgpt3.5的翻译,非常棒)如下:
这段文本描述了Rust中的 "reborrowing" 概念,即重新借用引用的特性,它实际上是 "autoborrow" 的
一种特殊情况。"reborrowing" 的核心思想是,当我们遇到一个类型为 &'a T 或 &'a mut T 的参数时,
我们总是会对它进行 "reborrow",实际上将其转换为 &'b T 或 &'b mut T。虽然这两者都是借用指针,
但 "reborrowed" 版本具有不同(通常更短)的生命周期。
下面通过一个示例来说明 "reborrowing" 为何重要:fn update(x: &mut i32) {*x += 1;
}fn update_twice(x: &mut i32) {update(x);update(x);
}
实际上,由于 "auto-borrowing",第二个函数会被隐式转换为:fn update_twice(x: &mut i32) {update(&mut *x);update(&mut *x);
}
这是因为 &mut 指针是 "affine" 的,这意味着否则第一次调用 update(x) 会将指针 x 移动到被调用的
函数内部,导致第二次调用时发生错误。但是,"reborrowing" 意味着我们实际上并没有移动 x,而是
移动了一个临时指针(我们称之为 y)。只要 y 存在,对 x 的访问就会被禁用,因此这与将 x 移动
出去非常相似。然而,生命周期推断将发现,临时指针 y 的生命周期仅限于第一次调用 update 本身,
因此在调用后访问 x 将会被恢复。借用检查规则允许在允许移动的情况下进行 "reborrowing",
因此此转换永远不会引入错3误。综上所述,"reborrowing" 是 Rust 中的一个重要借用模式,它有助于确保代码的安全性和正确性,
同时允许对数据进行操作而不引入潜在的错误。
这种机制是 Rust 借用系统的一部分,有助于编写安全且高效的代码。
总结一下,对于上面的代码而言:
// 下面这两行是等价的
add(ref1);
add(&mut *ref1);// 对于不可变引用而言也是一样的,但是由于不可变引用实现了Copy trait,通常在不可变引用身上不常见。let num2 = 456;
let ref2 = &num2;// 下面这两行是等价的
my_print(ref2);
my_print(&*ref2);fn my_print(num: &i32) {println!("{}", num);
}
至于为什么大量的文档和资料没有提到reborrow这个问题,可能得归结于此。在pull request中看到了核心开发者认为正式化reborrow时机不对。
NLL
在Rust的早期版本中,生命周期推断基于词法分析(Lexical analysis),而为了解决这个问题,Rust引入了非词法生命周期(Non-Lexical Lifetime),从而提高了编译器对生命周期的理解和推断。
Rust在1.31版本后提供的NLL(Non-Lexical Lifetime)生命周期简化规则。变量的生命周期跟它的作用域等同,而现在,变量的生命周期结束于它最后一次被使用的位置。
fn main() {let mut s = String::from("hello");let r1 = &s;let r2 = &s;println!("{} and {}", r1, r2);// 新编译器中,r1,r2作用域在这里结束let r3 = &mut s;println!("{}", r3);
} // 老编译器中,r1、r2、r3作用域在这里结束// 新编译器中,r3作用域在这里结束
在现在版本的rust编译器上,上面的代码可以通过正确编译,运行。有了NLL,大大增加了在rust中编写代码的灵活性。
相关文章:
rust中的reborrow和NLL
reborrow 我们看下面这段代码 fn main() {let mut num 123;let ref1 &mut num; // 可变引用add(ref1); // 传递给 add 函数println!("{}", ref1); // 再次使用ref1 }fn add(num: &mut i32) {println!("{}", *num); }我们…...
Java设计模式:一、六大设计原则-04:迪米特法则
文章目录 一、定义:迪米特法则二、模拟场景:迪米特法则原则三、违背方案:迪米特法则原则3.1 工程结构3.2 学生、老师、校长类3.2.1 学生类3.2.2 老师类3.2.3 校长类 3.3 单元测试 四、改善代码:迪米特法则原则4.1 工程结构4.2 学生…...
使用docker部署pg数据库
使用 Docker 部署 PostgreSQL 数据库是一种常见的做法,它提供了方便、可移植和可重复的方式来运行数据库。下面是一个简单的示例,用于在 Docker 中部署 PostgreSQL 数据库: 首先,确保您已经安装了 Docker 并正确配置了 Docker 环境…...

Json“牵手”亚马逊商品详情数据方法,亚马逊商品详情API接口,亚马逊API申请指南
亚马逊平台是美国最大的一家网络电子商务公司,亚马逊公司是1995年成立,刚开始只做网上书籍售卖业务,后来扩展到了其他产品。现在已经是全世界商品品种最多的网上零售商和第二互联网公司,亚马逊是北美洲、欧洲等地区的主流购物平台…...

springboot封装查询快递物流
目录 一、ApiClient代码解读二、ApiService代码解读三、HomeController代码解读四、整体代码五、结果展示 一、ApiClient代码解读 这是一个简单的Spring Boot的RestTemplate客户端,用于执行HTTP请求。 首先,这个类被Component注解标记,这意味…...

从C语言到C++_37(特殊类设计和C++类型转换)单例模式
目录 1. 特殊类设计 1.1 不能被拷贝的类 1.2 只能在堆上创建的类 1.3 只能在栈上创建的类 1.4 不能被继承的类 1.5 只能创建一个对象的类(单例模式)(重点) 1.5.1 饿汉模式 1.5.2 懒汉模式 2. 类型转换 2.1 static_cast 2.2 reinterpret_cast 2.3 const_cast 2.4 d…...
go 使用systray 实现托盘和程序退出
1.先 go get 安装 包 go get github.com/getlantern/systray2.使用的代码 func main() {fmt.Println("开始")systray.Run(onReady, onExit) }func onReady() {systray.SetIcon(icon.Data)systray.SetTitle("Awesome App")systray.SetTooltip("Prett…...
Electron之单例+多窗口
Electron之单例多窗口 Electron 24 React 18 单例可以通过app.requestSingleInstanceLock实现,多窗口可以简单通过路由来实现 单例 const gotTheLock app.requestSingleInstanceLock(); if (!gotTheLock) {app.quit(); } else {app.on(second-instance, (event, …...
A Survey of Knowledge-Enhanced Pre-trained Language Models
本文是LLM系列的文章,针对《A Survey of Knowledge-Enhanced Pre-trained Language Models》的翻译。 知识增强的预训练语言模型综述 摘要1 引言2 背景3 KE-PLMs用于NLU4 KE-PLMs用于NLG5 未来的方向5.1 整合来自同质和异质来源的知识5.2 探索多模态知识5.3 提供可…...
动态规划(选择)
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 作为队伍的核心,forever97很受另外两个队友的尊敬。 Trote_w每天都要请forever97吃外卖,但很不幸的是宇宙中心forever97所在的学校周围只有3家forever97爱吃的外卖。 如果T…...

IIS WebDAV配置,https绑定及asp设置
IIS支持标准CGI,因此可以用程序语言针对STDIN和STDOUT开发。 IIS CGI配置和CGI程序FreeBasic, VB6, VC 简单样例_Mongnewer的博客-CSDN博客 IIS支持脚本解释CGI,因此可以用脚本语言针对STDIN和STDOUT开发。 IIS perl python cbrother php脚本语言配置…...

【计算机视觉项目实战】中文场景识别
✨专栏介绍: 经过几个月的精心筹备,本作者推出全新系列《深入浅出OCR》专栏,对标最全OCR教程,具体章节如导图所示,将分别从OCR技术发展、方向、概念、算法、论文、数据集等各种角度展开详细介绍。 👨&…...
Java 中 Map 初始化的几种方法
# 传统方式 Map<String, String> map new HashMap<>(); map.put("k1", "v1"); map.put("k2", "v2");# java8新特性-双括号初始化 Map<String, String> map1 new HashMap<>() {{put("k1", "v…...
【学习方法论】学习的三种境界、三种习惯、三个要点,三个心态
学习的三种境界、三种习惯、三个要点,三个心态 三种学习境界 苦学 古人云:“头悬梁、锥刺股”,勤学苦练是第一境界。处于这种层次的同学,觉得学习枯燥无味,对他们来说学习是一种被迫行为,体会不到学习中的…...

[管理与领导-67]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 评估你与公司的八字是否相合
目录 前言: 一、概述 二、八字相合的步骤 2.1 企业文化是否相合 2.2.1 企业文化对职业选择的意义 2.2.2 个人与企业三观不合的结果 2.2.3 什么样的企业文化的公司不能加入 2.2 公司的发展前景 2.3 公司所处行业发展 2.4 创始人的三观 2.5 创始人与上司的…...

【PMO项目管理】深入了解项目管理 | Stakeholder 利益相关者 | 利益相关者之间的立场差异
💭 写在前面:本文将带您深入了解项目管理的核心概念和关键要素。我们将从项目管理的基本理解开始,逐步探讨其领域、复杂性和变化的重点,以及项目管理的具体过程。我们还将研究项目的性质以及成功项目所必备的条件。在此过程中&…...

设计模式-原则篇-01.开闭原则
简介 可以把设计模式理解为一套比较成熟并且成体系的建筑图纸,经过多次编码检验目前看来使用效果还不错的软件设计方案。适用的场景也比较广泛,在使用具体的设计模式之前先要学习软件设计的基础 “软件设计原则”,后面的23个设计模式都是…...

JAVA毕业设计096—基于Java+Springboot+Vue的在线教育系统(源码+数据库+18000字论文)
基于JavaSpringbootVue的在线教育系统(源码数据库18000字论文)096 一、系统介绍 本系统前后端分离 本系统分为管理员、用户两种角色(管理员角色权限可自行分配) 用户功能: 注册、登录、课程预告、在线课程观看、学习资料下载、学习文章预览、个人信息管理、消息…...

windows环境搭建ELK
目录 资源下载(8.9.1) ES安装、注册、使用 Kibana安装、注册、使用 Logstash安装、注册、使用 Filebeat安装、使用(如果只有一个数据流,则不需要使用filebeat,直接上logstash即可) 资源下载࿰…...

langchain介绍之-Prompt
LangChain 是一个基于语言模型开发应用程序的框架。它使得应用程序具备以下特点:1.数据感知:将语言模型与其他数据源连接起来。2.代理性:允许语言模型与其环境进行交互 LangChain 的主要价值在于:组件:用于处理语言模型…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...