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

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…...

【学习方法论】学习的三种境界、三种习惯、三个要点,三个心态

学习的三种境界、三种习惯、三个要点&#xff0c;三个心态 三种学习境界 苦学 古人云&#xff1a;“头悬梁、锥刺股”&#xff0c;勤学苦练是第一境界。处于这种层次的同学&#xff0c;觉得学习枯燥无味&#xff0c;对他们来说学习是一种被迫行为&#xff0c;体会不到学习中的…...

[管理与领导-67]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 评估你与公司的八字是否相合

目录 前言&#xff1a; 一、概述 二、八字相合的步骤 2.1 企业文化是否相合 2.2.1 企业文化对职业选择的意义 2.2.2 个人与企业三观不合的结果 2.2.3 什么样的企业文化的公司不能加入 2.2 公司的发展前景 2.3 公司所处行业发展 2.4 创始人的三观 2.5 创始人与上司的…...

【PMO项目管理】深入了解项目管理 | Stakeholder 利益相关者 | 利益相关者之间的立场差异

&#x1f4ad; 写在前面&#xff1a;本文将带您深入了解项目管理的核心概念和关键要素。我们将从项目管理的基本理解开始&#xff0c;逐步探讨其领域、复杂性和变化的重点&#xff0c;以及项目管理的具体过程。我们还将研究项目的性质以及成功项目所必备的条件。在此过程中&…...

设计模式-原则篇-01.开闭原则

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

JAVA毕业设计096—基于Java+Springboot+Vue的在线教育系统(源码+数据库+18000字论文)

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

windows环境搭建ELK

目录 资源下载&#xff08;8.9.1&#xff09; ES安装、注册、使用 Kibana安装、注册、使用 Logstash安装、注册、使用 Filebeat安装、使用&#xff08;如果只有一个数据流&#xff0c;则不需要使用filebeat&#xff0c;直接上logstash即可&#xff09; 资源下载&#xff0…...

langchain介绍之-Prompt

LangChain 是一个基于语言模型开发应用程序的框架。它使得应用程序具备以下特点&#xff1a;1.数据感知&#xff1a;将语言模型与其他数据源连接起来。2.代理性&#xff1a;允许语言模型与其环境进行交互 LangChain 的主要价值在于&#xff1a;组件&#xff1a;用于处理语言模型…...

汇编语言Nasmide编辑软件

用来编写汇编语言源程序&#xff0c;Windows 记事本并不是一个好工具。同时&#xff0c;在命令行编译源程序也令很多人迷糊。毕竟&#xff0c;很多年轻的朋友都是用着 Windows 成长起来的&#xff0c;他们缺少在 DOS和 UNIX 下工作的经历。 我一直想找一个自己中意的汇编语言编…...

用python开发一个炸金花小游戏

众所周知&#xfeff;扑克牌可谓是居家旅行、桌面交友的必备道具&#xff0c; 今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏&#xff0c;先来看一下基本的游戏规则。 炸&#xff08;诈&#xff09;金花又叫三张牌&#xff0c;是在全国广泛流传的一种民间多人纸牌游戏…...

Uniapp中使用uQRCode二维码跳转小程序页面

下载插件 uQRCode官网地址 引入插件 文件如下 //--------------------------------------------------------------------- // github https://github.com/Sansnn/uQRCode //---------------------------------------------------------------------let uQRCode = {};(functio…...

解决husky在mac下不生效的问题

目录 一、问题 1.1 问题描述 二、解决 2.1 解决 一、问题 1.1 问题描述 本文主要解决的问题是&#xff0c;husky在windows上正常生肖&#xff0c;但放到mac下后不生效的问题&#xff01; 为了确保团队中提交代码的一致性&#xff0c;因此使用了 husky 作为提交的检测工具…...

如何在自动化测试中使用MitmProxy获取数据返回?

背景介绍 当我们在接口或UI自动化项目中&#xff0c;常常会出现这种现象——明明是正常请求&#xff0c;却无法获取到想要的数据返回。 比如&#xff1a; 场景A&#xff1a;页面是动态数据&#xff0c;第一次进入页面获取到的数据&#xff0c;和下次进入页面获取到的数据完全…...

达之云BI平台助力中国融通集团陕西军民服务社有限公司实现数字化运营

中国融通集团陕西军民服务社是一家大型综合类零售购物中心&#xff0c;公司目前管理系统运行了10年左右&#xff0c;面临系统新零售支持发展严重滞后&#xff0c;行业主流应用落地困难&#xff0c;如线上业务、到家业务、全渠道营销、电子发票、自助收银、扫码购、无感停车、未…...

Private market:借助ZK实现的任意计算的trustless交易

1. 引言 Private market&#xff0c;借助zk-SNARKs和以太坊来 隐私且trustlessly selling&#xff1a; 1&#xff09;以太坊地址的私钥&#xff08;ECDSA keypair&#xff09;2&#xff09;EdDSA签名3&#xff09;Groth16 proof&#xff1a;借助递归性来匿名交易Groth16 proo…...

反序列化漏洞复现(typecho)

文章目录 执行phpinfogetshell 执行phpinfo 将下面这段代码复制到一个php文件&#xff0c;命名为typecho_1.0-14.10.10_unserialize_phpinfo.php&#xff0c;代码中定义的类名与typecho中的类相同&#xff0c;是它能识别的类&#xff1a; <?php class Typecho_Feed{const…...

QT设计一个小闹钟

设置一个闹钟&#xff0c;左侧窗口显示当前时间&#xff0c;右侧设置时间&#xff0c;以及控制闹钟的开关&#xff0c;下方显示闹钟响时的提示语。当按启动按钮时&#xff0c;设置时间与闹钟提示语均不可再改变。当点击停止时&#xff0c;关闭闹钟并重新启用设置时间与闹钟提示…...

MybatisPlus(3)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 一、查询投影&#x1f36d; 查询投影是指在查询操作中&#xff0c;只选择…...

南宁网站建设服务商/制作网页的基本步骤

最近开始动手做实验&#xff0c;之前写了一个小实验利用到了PCL库中的索引&#xff1b; 现在在写利用PCL中的RegionGrowing类来分割生成面片&#xff0c;无论是迭代生成还是进行提取都需要用到pcl库中定义的索引&#xff0c; 虽然搞的不是太明白&#xff0c;还是想写下来来记录…...

网页商城设计商城网站设计案例/代发新闻稿的网站

之前重点介绍了 Zynq All Programmable SoC 处理器系统 (PS) 中可用的私有定时器和看门狗。Zynq SoC 的 PS 还包含两个三重定时器计数器 (TTC)&#xff0c;可提供更加灵活的定时资源。您可以将这些 TTC 用作定时器或在 Zynq SoC 的 EMIO 或 MIO 引脚上输出波形。介绍下图取自Zy…...

温室大棚建设 网站及排名转卖/做网站用什么软件

文章目录1. 项目结构2. 页面组成3. json配置文件4. 认识页面5. WXML6. WXSS7. js文件8. 宿主环境9. 组件10. API11. 协同工作与发布跟公众号平台不共用一个账号&#xff0c;需要用其它邮箱另行注册&#xff0c;填写身份证信息&#xff08;姓名、身份证号码&#xff09;&#xf…...

做一家算命的网站/海外短视频软件

现在工作中很少使用原生的sql了&#xff0c;大多数的时候都在使用EF。刚开始的时候&#xff0c;只是在注重功能的实现&#xff0c;最近一段时间在做服务端接口开发。开发的时候也是像之前一样&#xff0c;键盘噼里啪啦的一顿敲&#xff0c;接口秒秒钟上线&#xff0c;但是到联调…...

潍坊网站网站建设/外链网站推荐几个

2019独角兽企业重金招聘Python工程师标准>>> 一、数据结构 程序设计数据结构算法 1.逻辑结构 1)集合&#xff1a;元素之间没有联系。 2)线性结构&#xff1a;元素之间存在前后顺序。 3)树形结构&#xff1a;元素之间存在一对多的父子关系。 4)图状结构&#xff1a;元…...

保定医疗网站建设公司/济南网站优化排名推广

一、前言 刚刚有一个好友向我咨询数据相关的问题&#xff0c;朋友目前是IT设备生产厂商的人。从好友的描述中&#xff0c;提到对用户特征获取的需求。包括&#xff1a;人的兴趣爱好、关注焦点等&#xff0c;在用户的描述中其实只是直觉性的列决出了几点&#xff0c;然后基于此作…...