rust引用

一、引用是什么

引用,又叫做借用。是一个指针类型。
引用是指向数据的指针,它允许我们以只读或可变的方式访问数据,而不获取数据的所有权。
编译器静态地保证了引用总是指向有效的对象。也就是说,当存在引用指向一个对象时,该对象不能被销毁

二、定义引用

在Rust中,使用&符号来创建引用。
(一)不可变引用
不可变引用,又叫共享引用。
不可变引用允许我们以只读方式访问数据,不允许修改数据。

语法格式

& type

示例:

fn main() {let mut x = 5;let y = &x;println!("x: {}", x);println!("y: {}", y);
}

可变变量x和不可变引用y,指向变量x的值。

(二)可变引用
可变引用允许我们以读写方式访问和修改数据。
语法格式

&mut type

示例:

let mut x = 5;
let y = &mut x;
*y += 1;
println!("x: {}", x);
println!("y: {}", y);

可变变量x和可变引用y,通过可变引用y修改了变量x的值。

引用的变量如果要变更,必须符合满足三个要求:
变量本身是可变的,也就是定义时必须添加 mut 关键字。
函数的参数也必须定义为可变的,也就是必须添加 &mut 关键字。
传递引用也必须是可变的,也就是传递参数时必须添加 &mut 关键字。
以上三个条件,任意一个不满足,都会报错。

三、使用引用

使用解引用操作符*来获取引用所指向的值

fn add_one(e: &mut i32) {*e+= 1;
}
fn main() {let mut i = 3;println!("before {}",i);add_one(&mut i);println!("after {}", i);
}
编译运行结果如下
before 3
after 4
let x = 5;
let y = &x;
assert_eq!(5, x);
assert_eq!(5, *y);
如果使用assert_eq!(5, y);,则会得到编译错误,不允许比较数字的引用与数字,因为它们是不同的类型。

四、悬垂引用

在具有指针的语言中,很容易通过释放内存时保留指向它的指针而错误地生成一个悬垂指针,悬垂指针也叫野指针,是其指向的内存可能已经被分配给其它人。它们就像失去悬挂物体的绳子,所以叫"悬垂指针"。
"悬垂引用"是一种悬垂指针。
在Rust语言里不允许出现悬垂引用
比如

fn main() {let reference_to_nothing = dangle();
}
fn dangle() -> &String {let s = String::from("hello");&s
}

编译错误。
因为 s 是在 dangle 函数内创建的,当 dangle 的代码执行完毕后,s 将被释放。返回的引用会指向一个无效的 String,这可不对!Rust不会允许我们这么做。
这里的解决方法是直接返回 String:

fn no_dangle() -> String {let s = String::from("hello");s
}

这样就没有任何错误了。所有权被移动出去,所以没有值被释放。

五、引用的规则

1.在同一时间点,要么 只能有一个可变引用,要么 只能有多个不可变引用。
2.引用必须总是有效的

一个引用的作用域从声明的地方开始一直持续到最后一次使用为止。
例如,

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 的作用域在 println! 之后结束,这也是创建可变引用 r3 的地方。它们的作用域没有重叠,所以代码是可以编译的。

比如,下面例子是错误的,因为同一时间存在多个可变引用。

let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);

下面例子也是错误的,因为同一时间既存在可变引用,又存在不可变引用

let mut s = String::from("hello");
let r1 = &s; // 没问题
let r2 = &s; // 没问题
let r3 = &mut s; // 大问题
println!("{}, {}, and {}", r1, r2, r3);

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

数码产品数码配件无线键盘等出口欧盟CE-RED认证测试办理

数码产品数码配件无线键盘CE-RED认证测试办理 无线产品CE-RED认证进入东欧市场规定: 在通信终端设备和无线产品在这些/地区合法销售之前,必须按照 RED 指令进行测试,并且还必须提供 CE 标志。无线远程控制产品必须符合 RED 指令的 REDEU 要…

华为云HECS云服务器docker环境下安装nginx

前提:有一台华为云服务器。 华为云HECS云服务器,安装docker环境,查看如下文章。 华为云HECS安装docker-CSDN博客 一、拉取镜像 下载最新版Nginx镜像 (其实此命令就等同于 : docker pull nginx:latest ) docker pull nginx查看镜像 dock…

JS对象数组去重

JS对象数组去重 一、数组去重1.使用 new Set()2.使用 indexOf 去重3.使用 includes 去重4.使用 hasOwnProperty5.使用 filter6.使用递归7.利用 Map 数据结构去重8.使用用 reduce includes9.使用 new Set() 的简化 二、对象数组去重1.使用 new Map() 和 filter2.使用reduce3.使…

【JVM】第四篇 垃圾收集器ParNewCMS底层三色标记算法详解

导航 一. 垃圾收集算法详解1. 分代收集算法2. 标记-复制算法3. 标记-清除算法4. 标记-整理算法二. 垃圾收集器详解1. Serial收集器2. Parallel Scavenge收集器3. ParNew收集器4. CMS收集器三. 垃圾收集底层三色标记算法实现原理1. 垃圾收集底层使用三色标记算法的原因?2. 垃圾…

计算机竞赛 深度学习图像分类算法研究与实现 - 卷积神经网络图像分类

文章目录 0 前言1 常用的分类网络介绍1.1 CNN1.2 VGG1.3 GoogleNet 2 图像分类部分代码实现2.1 环境依赖2.2 需要导入的包2.3 参数设置(路径,图像尺寸,数据集分割比例)2.4 从preprocessedFolder读取图片并返回numpy格式(便于在神经网络中训练)2.5 数据预…

1.centos7 安装显卡驱动、cuda、cudnn

安装conda 参考 python包 2.安装conda python库-CSDN博客 1.安装显卡驱动 步骤1:安装依赖 yum -y install kernel-devel yum -y install epel-release yum -y install gcc 步骤2:查询显卡版本 lspci | grep VGA 找到2230号码,进入如下网…

Swift data范围截取问题

文章目录 一、截取字符串的几种方法1. 截取前几位2. 截取后几位3. subData4. 下标截取 二、subData(in:) 报错 EXC_BREAKPOINT 一、截取字符串的几种方法 1. 截取前几位 mobileID.prefix(32)2. 截取后几位 mobileID.suffix(3)3. subData data.subdata(in: 0..<4)4. 下标…

大学生登记国家证书软件著作权提升就业资质

大学生登记国家证书软件著作权提升就业资质 随着信息技术的快速发展&#xff0c;软件行业成为了许多大学生就业的热门选择之一。然而&#xff0c;在竞争激烈的就业市场中&#xff0c;除了掌握专业知识和技能外&#xff0c;如何提升自己的就业资质也显得尤为重要。其中&#xff…

postman接口测试系列: 时间戳和加密

在使用postman进行接口测试的时候&#xff0c;对于有些接口字段需要时间戳加密&#xff0c;这个时候我们就遇到2个问题&#xff0c;其一是接口中的时间戳如何得到&#xff1f;其二就是对于现在常用的md5加密操作如何在postman中使用代码实现呢&#xff1f; 下面我们以一个具体的…

selenium不定位元素直接使用键盘操作(如弹框操作)

今天在使用selenium进行定位时&#xff0c;发现直接定位不了chrome的弹框&#xff0c;如这种弹框&#xff1a; 使用的是下面这行代码 driver.switch_to.alert.accept() 运行报错&#xff0c;说是没有 alert windown。。。。 啊&#xff1f;难道chrome的弹框不是用alert写的&…

冲刺十五届蓝桥杯P0001阶乘求和

文章目录 题目描述思路分析代码解析 题目描述 思路分析 阶乘是蓝桥杯中常考的知识。 首先我们需要知道 int 和long的最大值是多少。 我们可以知道19的阶乘就已经超过了long的最大值&#xff0c;所以让我们直接计算202320232023&#xff01;的阶乘是不现实的。 所以我们需要…

WhatsOnChain中的sCrypt合约验证插件

我们很高兴地宣布在 WhatsOnChain 上集成了 sCrypt 智能合约验证插件。该插件允许任何人为已部署的智能合约提交和验证 sCrypt 代码。 智能合约验证 在与智能合约交互之前&#xff0c;用户需要确保智能合约按照其声称的方式行事。理论上&#xff0c;每个人都可以查看合约并验…

链表oj题2(Leetcode)(牛客)——合并两个有序链表;判断回文链表;链表分割

链表oj题2&#xff08;Leetcode&#xff09;&#xff08;牛客&#xff09; 一&#xff0c;合并两个有序链表1.1分析2.2代码 二&#xff0c;链表的回文结构2.1分析2.2代码 三&#xff0c;链表分割3.1分析3.2代码 四&#xff0c;小结 一&#xff0c;合并两个有序链表 合并两个有…

苹果曾考虑基于定位控制AirPods Pro自适应音频

在一次最近的采访中&#xff0c;苹果公司的高管Ron Huang和Eric Treski透露&#xff0c;他们在开发AirPods Pro自适应音频功能时&#xff0c;曾考虑使用GPS信号来控制音频级别。这个有趣的细节打破了我们对AirPods Pro的固有认知&#xff0c;让我们对苹果的创新思维有了更深的…

趣解设计模式之《小王的糖果售卖机》

〇、小故事 小王最近一直在寻找商机&#xff0c;他发现商场儿童乐园或者中小学校周围&#xff0c;会有很多小朋友喜欢吃糖果&#xff0c;那么他想设计一款糖果售卖机&#xff0c;让后将这些糖果售卖机布置到商场和学校旁边&#xff0c;这样就能获得源源不断的收益了。 想到这里…

关闭手机广告的步骤

关闭手机广告的步骤 小米 1.设置→小米账号→声明与条款→系统广告→系统工具广告→关闭 2.设置→应用设置→应用管理→右上角三个点→设置→关闭“应用升级提醒”&“资源推荐” 3.桌面左滑打开负一屏→划到底部→设置→服务管理→选择关闭项目 4.桌面→打开任意文件夹…

工厂与观察者模式

工厂模式介绍 通过一个加工厂&#xff0c;在这个工厂中添加对应材料&#xff0c;我们就可以得到想要的东西&#xff0c;在程序设计中&#xff0c;这种模式就叫做工厂模式&#xff0c;工厂生成出的产品就是某个类的实例&#xff0c;也就是对象。 关于工厂模式一共有三种&#…

【zookeeper】基于Linux环境安装zookeeper集群

前提&#xff0c;需要有几台linux机器&#xff0c;我们可以准备好诸如finalshell来连接linux并且上传文件&#xff1b; 其次Linux需要安装上ssh&#xff0c;并且在/etc/hosts文件中写好其他几台机器的名字和Ip 127.0.0.1 localhost localhost.localdomain localhost4 localh…

【精彩回顾】 用sCrypt在Bitcoin上构建智能合约(2)

2023年3月30日&#xff0c;sCrypt首席执行官刘晓晖在英国伦敦nChain做了题为“用sCrypt在Bitcoin上构建智能合约”的演讲&#xff0c;并与现场来宾进行了深入交流、互动。这次课程着重讲解了 BSV 智能合约的基础概念&#xff0c;以及如何利用 sCrypt 的相关工具构建应用。 ▲英…

MATLAB 多信号显示方案

效果示例 重要参考资料 MATLAB官方资料 matlab plot3 函数说明 利用for循环和plot函数画多条曲线时如何添加图例&#xff1f; x1:100; krandperm(20)‘; A{‘aa’,‘bb’,‘ccc’,‘ddd’}; y(k*x)’ for i1:20 plot(x,y(:,i)) STRsprintf(‘曲线%d’,i); A(i)cellstr(STR); …