Rust入门-引用借用

news2025/1/15 6:45:50

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

所有权上篇我们已经讨论过了,所以这篇我们讨论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.coloradmin.cn/o/1609070.html

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

相关文章

CERLAB无人机自主框架: 1-环境搭建

前言:更多更新文章详见我的个人博客主页【MGodmonkeyの世界】 描述:欢迎来到CERLAB无人机自主框架,这是一个用于自主无人飞行器 (UAV) 的多功能模块化框架。该框架包括不同的组件 (模拟器,感知,映射,规划和…

【数据结构-串-数组-广义表】

目录 1 串-理解1.1 串的抽象定义:-理解1.2 串的存储结构-不断掌握1.2.1 顺序存储结构:1.2.2 链式存储结构: 1.3 串的模式匹配算法:-掌握1.3.1 BF暴力求解算法-代码 -掌握1.3.2 KMP求解算法-代码--掌握 2 数组-不断掌握2.1 顺序存储…

vue-cli2 与vue-cli3,vue2与vue3 初始化项目,本地vue项目,详细解析区别(2024-04-19)

目录 1、区别(vue-cli2 与 vue-cli3 ) 2、例子1(vue2项目) 2.1 版本与命令行 2.2 项目本地截图 2.3 项目文件解析 (1)package.json 文件 (2)webpack.dev.conf.js文件 &#…

PTA图论的搜索题

目录 7-1 列出连通集 题目 输入格式: 输出格式: 输入样例: 输出样例: AC代码 7-2 六度空间 题目 输入格式: 输出格式: 输入样例: 输出样例: 思路 AC代码 7-3 地下迷宫探索 题目 输入格式: 输出格式: 输入样例1: 输出样例1: 输入样例2: 输出样例2: 思路 …

股票战法课程之主力的痕迹

文章目录 1. 主力的操作痕迹2. 主力的建仓2.1 建仓的三种方式2.2 建仓的五个特点2.3 建仓的迹象2.4 建仓的成交量特征 1. 主力的操作痕迹 序号痕迹原因1不跟随大盘节奏筹码都在主力手中2突发利空消息,股价不跌反涨主力被套,不希望散户抛盘3很小的成交量…

【初识Qt】如何使用QtCreator创建项目

文章目录 1 :peach:Qt Creator 概览:peach:2 :peach:使⽤ Qt Creator 新建项目:peach:2.1 :apple:新建项目:apple:2.2 :apple:使用标签实现 Hello World 程序:apple:2.2.1 :lemon:纯代码方式实现:lemon:2.2.2 :lemon:可视化操作实现:lemon: 2.3 :apple:使用按钮实现 Hello Worl…

vue element-ui 表格横向滚动条在合计项下方

目前效果 需求效果 1.隐藏bodyWrapper滚动条,显示footerWrapper滚动条 css代码如下: div ::v-deep .el-table--scrollable-x .el-table__body-wrapper{overflow-x: hidden!important;z-index: 2!important;} div ::v-deep .el-table__footer-wrapper …

WWW ‘24 | EarnMore: 如何利用强化学习来处理可定制股票池中的投资组合管理问题

WWW 24 | EarnMore: 如何利用强化学习来处理可定制股票池中的投资组合管理问题 原创 QuantML QuantML 2024-04-16 09:04 上海 Content 本文主要探讨了如何利用强化学习(Reinforcement Learning, RL)来处理可定制股票池(Customizable Stock …

关于RA8900CE时钟芯片的使用注意事项

在快节奏的现代社会&#xff0c;时间变得越来越宝贵。对于时钟的电子设计&#xff0c;高精度且低功耗逐渐成为主流。我们就有一个汽车显示屏的时钟显示项目&#xff0c;要求时钟一天的误差控制在1s以内。要想达到此要求&#xff0c;则必须满足晶振的频率偏差PPM<1/60/60/24*…

【Hadoop大数据技术】——Sqoop数据迁移(学习笔记)

&#x1f4d6; 前言&#xff1a;在实际开发中&#xff0c;有时候需要将HDFS或Hive上的数据导出到传统关系型数据库中&#xff08;如MySQL、Oracle等&#xff09;&#xff0c;或者将传统关系型数据库中的数据导入到HDFS或Hive上&#xff0c;如果通过人工手动进行数据迁移的话&am…

微博聚类文本分析和可视化

本文使用python抓取微博数据并对微博文本分析和可视化&#xff0c;LDA&#xff08;树图&#xff09;、关系图、词云、时间趋势&#xff08;折线图&#xff09;、热度地图、词典情感分析&#xff08;饼图和3D柱状图&#xff09;、词向量神经网络情感分析、tfidf聚类、词向量聚类…

go语言并发实战——日志收集系统(四) 利用tail包实现对日志文件的实时监控

Linux中的tail命令 tail 命令是一个在 Unix/Linux 操作系统上用来显示文件末尾内容的命令。它可以显示文件的最后几行内容&#xff0c;默认情况下显示文件的最后 10 行。tail 命令 非常有用&#xff0c;特别是在我们查看日志文件或者监视文件变化时。 基本用法如下&#xff1a…

搭建sql-lab出现的php不兼容

下载不了的时候&#xff0c;直接打开该网址下载5.xphp版本&#xff0c;解压到C:\php_studyv8\phpstudy\phpstudy_pro\Extensions\php&#xff08;可能路径都不一样&#xff0c;找到Extensions\php放到该目录下&#xff09;

Excel模板导入、导出工具类

1.引入maven依赖&#xff0c;利用hutool的excel读取 Hutool-poi对excel读取、写入 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency> <depen…

期权小知识科普

期权的交易时间 上交所期权合约的交易时间为每个交易日9:15至9:25、9:30至11:30、13&#xff1a;00至15:00。 其中&#xff0c;9:15至9:25为开盘集合竞价时间&#xff0c;14:57-15:00为收盘集合竞价时间&#xff0c;其余时段为连续竞价时间&#xff0c;交易所规则另有规定的除…

后台管理系统加水印(react)

效果 代码图片 代码 window.waterMark function (config) {var defaultConfig {content: 我是水印,fontSize: 16px,opacity: 0.3,rotate: -15,color: #ADADAD,modalId: J_waterMarkModalByXHMAndDHL,};config Object.assign({}, defaultConfig, config);var existMarkModal…

Hadoop3:大数据的基本介绍

一、什么是大数据 1、大数据的4v特点 Volume&#xff08;大量&#xff09; Velocity&#xff08;高速&#xff09; Variety&#xff08;多样&#xff09; Value&#xff08;低价值密度&#xff09; 2、大数据部门间的工作岗位 第三部分&#xff0c;其实就是JavaWeb 二、…

李沐53_语言模型——自学笔记

语言模型 1.预测文本序列出现的概率 2.应用在做预训练模型 3.生成文本&#xff0c;给定前面几个词&#xff0c;不断生成后续文本 4.判断多个序列中哪个更常见 真实数据集的统计 《时光机器》数据集构建词表&#xff0c; 并打印前10个最常用的&#xff08;频率最高的&…

4.4 @ControllerAdvice全局数据处理

顾名思义&#xff0c;&#xff20;ControllerAdvice 就是&#xff20;Controller 增强版。&#xff20;ControllerAdvice 主要用来处理全 局数据 ,一般搭配&#xff20;ExceptionHandler、&#xff20;ModelAttribute 及&#xff20;InitBinder 使用。 1. 全局异常处理&#x…

密文字段模糊检索方案

代码地址: https://github.com/zuiyu-main/EncryptDemo https://mp.weixin.qq.com/s/cXOg1tiMtJz2eibDZmXHUQ 在个别特殊领域中&#xff0c;数据的安全问题是非常的重要的&#xff0c;所以需要数据库存储的数据是需要加密存储的。所以也就引申出来本文这个问题&#xff0c;加密…