Rust入门-引用借用

一、引用借用,是什么、为什么、怎么用

所有权上篇我们已经讨论过了,所以这篇我们讨论Rust的引用借用

1、引用借用 是什么?

Rust 通过借用(Borrowing) 这个概念来达成上述的目的,获取变量的引用,称之为借用(borrowing)。

其实就是指针,在Rust叫借用,只不过Rust的借用会比指针的使用更严格一点。

2、为什么要有引用借用

所有权很强大,避免了内存的不安全性,但是也带来了一个新麻烦: 总是把一个值传来传去来使用它。 传入一个函数,很可能还要从该函数传出去,结果就是语言表达变得非常啰嗦,幸运的是,Rust 提供了新功能解决这个问题。

3、怎么用

我们先来看一个简单的例子

fn main() {let x = 5;let y = &x;//获取了不可变变量x的引用,y本身是不可变的变量assert_eq!(5, x);assert_eq!(5, *y);//获取引用所指向地址的值,和其它语言类似,通过*来获取
}

这段代码中,y获取了不可变变量x的引用。

那么y不可变 引用,在这个不可变引用一词中,“不可变”指的是该引用不可以修改所指向的!一定要主要这个区别。

y也是一个不可变变量,这里的不可变,指的是y不可以指向别的变量,或者是说不可以修改y的值,要和不可变引用进行区别

通过一段代码和图来进一步理解

fn main() {let s1 = String::from("hello");let len = calculate_length(&s1);println!("The length of '{}' is {}.", s1, len);
}fn calculate_length(s: &String) -> usize {s.len()
}

前面这段代码,效果是这样的请添加图片描述

通过 &s1 语法,我们创建了一个指向 s1 的引用,但是并不拥有它

因为并不拥有这个值,当引用离开作用域后,其指向的值也不会被丢弃

同时,&s1也是一个不可变引用,我们不可以修改该引用指向的值,如果我们要修改,就会报错

fn main() {let s = String::from("hello");change(&s);
}fn change(some_string: &String) {some_string.push_str(", world");
}
error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` reference--> src/main.rs:8:3|
8 |   some_string.push_str(", world");|   ^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable|
help: consider changing this to be a mutable reference|
7 | fn change(some_string: &mut String) {|        

3、可变引用

那我们想通过引用来修改引用指向的值该怎么办,这时候就有可变引用

fn main() {let mut s = String::from("hello");change(&mut s);
}fn change(some_string: &mut String) {some_string.push_str(", world");
}

这样就能完成修改。

这里一共有关键的两步

  1. 声明 s 是可变类型
  2. 其次创建一个可变的引用 &mut s 和接受可变引用参数 some_string: &mut
    String 的函数。注意是&mut

接下来我们聊一下可变引用的一些使用注意事项

可变引用同时只能存在一个

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

这段代码会报错

error[E0499]: cannot borrow `s` as mutable more than once at a time 同一时间无法对 `s` 进行两次可变借用--> src/main.rs:5:14|
4 |     let r1 = &mut s;|              ------ first mutable borrow occurs here 首个可变引用在这里借用
5 |     let r2 = &mut s;|              ^^^^^^ second mutable borrow occurs here 第二个可变引用在这里借用
6 |
7 |     println!("{}, {}", r1, r2);|                        -- first borrow later used here 第一个借用在这里使用

可变引用与不可变引用不能同时存在

let mut s = String::from("hello");let r1 = &s; // 没问题
let r2 = &s; // 没问题
let r3 = &mut s; // 大问题println!("{}, {}, and {}", r1, r2, r3);
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable// 无法借用可变 `s` 因为它已经被借用了不可变--> src/main.rs:6:14|
4 |     let r1 = &s; // 没问题|              -- immutable borrow occurs here 不可变借用发生在这里
5 |     let r2 = &s; // 没问题
6 |     let r3 = &mut s; // 大问题|              ^^^^^^ mutable borrow occurs here 可变借用发生在这里
7 |
8 |     println!("{}, {}, and {}", r1, r2, r3);|                                -- immutable borrow later used here 不可变借用在这里使用

注意,引用的作用域 s 从创建开始,一直持续到它最后一次使用的地方,这个跟变量的作用域有所不同,变量的作用域从创建持续到某一个花括号 }

给大家一段代码看看,Rust真好玩(手动狗头)

fn main() {let mut s = String::from("hello, ");let mut y=&mut s;y.push_str("world");println!("{}",y)
}fn push_str(s: &mut String) {s.push_str("world")
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

维护SQLite的私有分支(二十六)

返回:SQLite—系列文章目录 上一篇:SQLite、MySQL 和 PostgreSQL 数据库速度比较(本文阐述时间很早比较,不具有最新参考性)(二十五) 下一篇:SQLite数据库中JSON 函数和运算符 1…

汇编语言 实验10.1

汇编语言 实验10.1 assume cs:code,ds:datasgdatasg segmentdb welcome to masm!,0 datasg endsstack segmentdw 0,0,0,0,0,0,0,0 stack endscode segment ;代码段start: mov dh,8mov dl,3mov cl,2mov ax,datasgmov ds,axmov si,0call show_strmov ax,4c00h ;程序返回int 21hs…

已经下载了pytorch,但在正确使用一段时间后出现No module named torch的错误

问题描述 使用的是叫做m2release的虚拟环境,在此环境下使用conda list可以发现是存在pytorch的,但是运行代码时却报No module named torch的错误。 解决方案 想尝试卸掉这个pytorch重新装一次,但是想卸载会提示找不到,想重新…

Java八股文4

Linux篇 1.free命令-查看内存状态 free命令用于显示内存状态,它可以提供关于系统内存使用情况的详细信息。这个命令会显示出内存的使用情况,包括实体内存、虚拟的交换文件内存、共享内存区段,以及系统核心使用的缓冲区等。 其中,参…

每三人拥有一辆车!车载工业平板电脑五大硬性要求

在今年7月初,公安部发布2022年上半年全国机动车和驾驶人统计数据,数据显示,截至2022年6月底,全国机动车保有量达4.06亿辆,其中汽车3.10亿辆。此外,目前全国拥有驾驶证的人数高达4.92亿人,其中汽…

一文读懂电阻并联电路和串联电路的特性

电阻并联电路是最基本的并联电路,所有的电路都可以转化为电阻串联电路和电阻并联电路来了解其工作原理。并联电路和串联电路具有完全不同的特性。它们是完全不同的电路,不能相互等效(电阻并联电路图)。 串联电路 特点与特性&…

探索半导体测试领域:哲讯TCC智能化管理系统的应用与优势

在半导体行业中,封装和测试环节是至关重要的一环。半导体封装测试是指将通过测试的晶圆按照产品型号及功能需求加工得到独立芯片的过程。半导体封测包括封装和测试两个环节,封装是保护芯片免受物理、化学等环境因素造成的损伤,增强芯片的散热…

es安装中文分词器

下载地址,尽量选择和自己本地es差不多的版本 https://github.com/infinilabs/analysis-ik/releases 下载好,解压,把里面的文件放到es的plugins/ik目录下 把plugin-descriptor.properties文件里的es版本改成自己对应的 再启动es,能…

Mamba 学习

Vision Mamba U-Mamba 以后的趋势: 1.Mamba模型机机制上和transform一样,但是参数量上做了改进,可以直接替代 2.vision上可以实时处理

深入剖析跨境电商平台风控机制,探索测评安全与稳定的秘诀

在跨境电商测评市场鱼龙混杂的当下,测评过程中可能隐藏的陷阱保持高度警觉。多年的测评经验告诉我们,选择一个适合的测评系统对于项目的成功至关重要。近年来,测评技术如雨后春笋般涌现,市场上涌现出众多测评系统,覆盖…

Java 的注释

文章目录 java 的注释共有三种形式单行注释多行注释文档注释文档注释的文档需要命令进行生成GBK 不可映射问题 与大多数的编程语言一样,Java 中的注释也不会出现在可执行程序中。 因此我们可以在源程序中根据需要添加任意多的注释,而不必担心可执行代码受…

了解光纤的最大损耗

在电信和数据传输领域,保持最佳的网络性能和可靠性至关重要。 影响网络完整性的关键因素之一是光纤中的信号丢失。信号损耗,也称为衰减损耗或光纤衰减,测量光缆输入和输出之间的光损耗量。本文将深入探讨光纤中的主要损耗,并指导您…

使用yolov5训练自己的目标检测模型

使用yolov5训练自己的目标检测模型 使用yolov5训练自己的目标检测模型1. 项目的克隆2. 项目代码结构3. 环境的安装和依赖的安装4. 数据集和预训练权重的准备4.1利用labelimg标注数据和数据的准备4.1.1 **labelimg介绍:**4.1. 2 labelimg的安装 4.2 使用labelimg4.2.1 数据准备4…

开源在线表单工具 HeyForm 使用教程

HeyForm 是一个非常出色的开源在线表单工具,可以通过直观的拖拽式编辑器,快速构建出美观实用的表单。 HeyForm 的功能非常丰富: 支持丰富的输入类型,从基础的文本、数字到高级的图片选择、日期选择、文件上传等,一应俱…

Nginx第3篇-使用ngx_http_proxy_connect_module配置https正向代理

场景 我使用python爬虫,然后需要个代理,所以就用Nginx搭了一个代理服务器。对Nginx也不太熟,慢慢摸索,搭建完之后发现只能代理http的请求,无法穿透https。几经折腾和摸索发现一个强大的HTTP代理模块:ngx_h…

配置静态IP【windows+ubuntu】

Windows配置静态IP 如下图所示,通过“网络和Internet进入设置界面”,依次操作“更改适配器选项”->选择要配置静态ip的网络“属性”->选择IPV4的属性->配置静态ip的地址、子网掩码、默认网关。默认网关应和路由器上的设置保持一致。 Ubuntu配…

SL7220线性降压恒流3.6A 外围只需两个电阻 耐压40V汽车大灯IC

概述: SL7220 是一款双路线性降压LED恒流驱动器,外围只需两个电阻,输出电流10MA-3600MA。 SL7220 内置过热保护功能,内置输入过压保护功能。 SL7220 静态电流典型值为120uA。 特点 ●输入电压范围:2.5V-40V ●电…

Matlab方程组拟合【案例源码+视频教程】

专栏导读 作者简介:工学博士,高级工程师,专注于工业软件算法研究本文已收录于专栏:《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法,并提供所有案例完整源码;2.…

OpenHarmony轻量系统开发【6】驱动之ADC按键

摘要:本文简单介绍如何操作ADC去读取电压,并且实现开发板上3个ADC按键检测的功能 适合群体:适用于润和Hi3861开发板,L0轻量系统驱动开发 文中所有代码仓库:https://gitee.com/qidiyun/hihope-3861-smart-home-kit 6…

如何识别伪装IP的网络攻击

伪装IP的网络攻击是一种通过篡改或伪造IP地址,冒充合法用户或服务器,发起恶意网络请求的攻击方式。这种攻击具有极强的隐蔽性,使得受害者在遭受攻击后难以找到真实的攻击者。为了识别伪装IP的网络攻击,我们可以采取以下几种方法&a…