【Rust】引用与借用

目录

思维导图

1. 引用与借用的基本概念

1.1. 引用示例

2. 借用的规则

2.1. 可变借用示例

2.2. 借用的限制

3. 引用的生命周期


思维导图

1. 引用与借用的基本概念

  • 引用的定义引用是一种指向数据的指针,但与裸指针不同,Rust的引用在编译时受到严格的规则约束,确保其始终指向有效的内存区域。引用分为不可变引用(&T)和可变引用(&mut T)。
  • 借用的意义借用是指在不获取数据所有权的情况下,通过引用访问或修改数据的过程。借用机制允许在多个上下文中共享数据,同时避免数据竞争和内存安全问题。

1.1. 引用示例

  • 示例1:计算字符串长度
    fn main() {
        let text = String::from("hello");
        let length = calculate_string_length(&text); // 传递不可变引用
        println!("The length of '{}' is {}.", text, length);
    }
    
    // 计算字符串长度的函数
    fn calculate_string_length(s: &String) -> usize {
        s.len() // 通过引用访问数据
    }
    • 在这个示例中,calculate_string_length函数接受一个字符串的引用&text,而不是直接获取String的所有权。这允许main函数在调用后继续使用text

2. 借用的规则

  • 不可变借用当一个值被不可变引用借用时,该值在借用期间不能被修改。允许多个不可变引用同时存在,确保数据的一致性。
  • 可变借用若要修改借用的值,必须使用可变引用&mut。Rust强制要求在同一时间只能有一个可变引用,或者多个不可变引用,但两者不能共存。这一规则防止了数据竞争的发生。

2.1. 可变借用示例

  • 示例2:修改借用的字符串
    fn main() {
        let mut s = String::from("hello");
        append_text(&mut s); // 传递可变引用
        println!("{}", s); // 输出修改后的字符串
    }
    
    // 修改字符串的函数
    fn append_text(s: &mut String) {
        s.push_str(", world"); // 通过可变引用修改数据
    }
    • 在这个示例中,s被声明为可变,并通过&mut s传递给append_text函数,允许对s进行修改。

2.2. 借用的限制

  • 多个可变引用的限制Rust禁止在同一作用域内同时存在多个可变引用,以防止数据竞争(data races)。数据竞争可能导致未定义行为,因此Rust在编译时严格检查此类问题。
  • 可变与不可变引用的限制:当同一个值有一个不可变引用时,便不能再拥有一个可变引用。
  • 示例3:多个可变引用的错误
    fn main() {
        let mut message = String::from("hello");
    
        let first_ref = &mut message; // 第一个可变引用
        // let second_ref = &mut message; // 取消注释会导致编译错误
    
        println!("First reference: {}", first_ref);
        // println!("Second reference: {}", second_ref); // 无法同时使用两个可变引用
    }
    • 此代码尝试同时创建两个可变引用,导致编译错误。

3. 悬空引用

  • Rust通过生命周期(lifetime)机制确保引用在使用期间始终指向有效的内存区域,避免了悬空引用的问题。生命周期是Rust编译器在编译时进行静态检查的重要工具。

  • 示例4:悬空引用的错误
    fn main() {
        // let dangling_ref = create_dangling_reference(); // 取消注释会导致编译错误
        // println!("{}", dangling_ref); // 无法使用悬空引用
    }
    
    // 尝试返回局部变量引用的函数
    fn create_dangling_reference() -> &String {
        let s = String::from("hello");
        &s // 编译错误:返回局部变量的引用
    }
    • 该示例试图返回一个局部变量的引用,导致编译错误,因为&s在函数结束后S会被释放。

tips: 

  • 在任何时候,你都可以拥有要么一个可变引用要么任意数量的不可变引用。
  • 引用必须始终有效。

补充:常见数据竞争:

  • 两个或多个指针同时访问相同的数据。
  • 至少有一个指针正在用于写入数据。
  • 没有使用任何机制来同步对数据的访问。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《自动驾驶与机器人中的SLAM技术》ch8:基于 IESKF 的紧耦合 LIO 系统

紧耦合系统,就是把点云的残差方程直接作为观测方程,写入观测模型中。这种做法相当于在滤波器或者优化算法内置了一个 ICP 或 NDT。因为 ICP 和 NDT 需要迭代来更新它们的最近邻,所以相应的滤波器也应该使用可以迭代的版本,ESKF 对…

Mac 删除ABC 输入法

参考链接:百度安全验证 Mac下删除系统自带输入法ABC,正解!_mac删除abc输入法-CSDN博客 ABC 输入法和搜狗输入法等 英文有冲突~~ 切换后还会在英文状态,可以删除 ;可能会对DNS 输入有影响,但是可以通过复…

1.13 多线程编程

1.思维导图 2.创建两个子进程,父进程负责:向文件中写入数据;两个子进程负责:从文件中读取数据。 要求:一定保证1号子进程先读取,2号子进程后读取,使用文件IO去实现。 1>程序代码 …

Elasticsearch ES|QL 地理空间索引加入纽约犯罪地图

可以根据地理空间数据连接两个索引。在本教程中,我将向你展示如何通过混合邻里多边形和 GPS 犯罪事件坐标来创建纽约市的犯罪地图。 安装 如果你还没有安装好自己的 Elasticsearch 及 Kibana 的话,请参考如下的链接来进行安装。 如何在 Linux&#xff0…

数据分析-使用Excel透视图/表分析禅道数据

背景 禅道,是目前国内用得比较多的研发项目管理系统,我们常常会用它进行需求管理,缺陷跟踪,甚至软件全流程的管理,如果能将平台上的数据结公司的实际情况进行合理的分析利用,相信会给我们的项目复盘总结带来…

【c语言】指针 (完结)

一、sizeof和strlen的对比 1、sizeof 前面我们在学习操作符的时候,我们学习了sizeof,知道其是计算变量所占内存的大小的,单 位是字节,如果操作数是数据类型的话,计算的就是这个类型的变量所占的内存空间的大…

Chromium 132 编译指南 Windows 篇 - 生成构建文件 (六)

1. 引言 在上一篇文章中,我们已经成功获取了 Chromium 的源代码并同步了相关的第三方依赖。本文将继续深入,指导您如何使用 GN 工具生成构建文件,为接下来的编译工作奠定基础。 2. 切换 Chromium 版本至 132 在开始正式构建之前&#xff0…

(12)springMVC文件的上传

SpringMVC文件上传 首先是快速搭建一个springMVC项目 新建项目mvn依赖导入添加webMoudle添加Tomcat运行环境.在配置tomcat时ApplicationContext置为"/"配置Artfact的lib配置WEB-INF配置文件(记得添加乱码过滤)配置springmvc-servlet文件&…

3D目标检测数据集——Waymo数据集

Waymo数据集簡介 发布首页:https://waymo.com/open/ 论文:https://openaccess.thecvf.com/content_CVPR_2020/papers/Sun_Scalability_in_Perception_for_Autonomous_Driving_Waymo_Open_Dataset_CVPR_2020_paper.pdf github:https://github.…

Mysql--运维篇--空间管理(表空间,索引空间,临时表空间,二进制日志,数据归档等)

MySQL的空间管理是指对数据库存储资源的管理和优化。确保数据库能够高效地使用磁盘空间、内存和其他系统资源。良好的空间管理不仅有助于提高数据库的性能,还能减少存储成本并防止因磁盘空间不足导致的服务中断。MySQL的空间管理涉及多个方面,包括表空间…

STM32之LWIP网络通讯设计-下(十五)

STM32F407 系列文章 - ETH-LWIP(十五) 目录 前言 一、软件设计 二、CubeMX实现 1.配置前准备 2.CubeMX配置 1.ETH模块配置 2.时钟模块配置 3.中断模块配置 4.RCC及SYS配置 5.LWIP模块配置 3.生成代码 1.main文件 2.用户层源文件 3.用户层头…

Gateway 网关

1.Spring Cloud Gateway Spring cloud gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态…

数据结构:栈(Stack)和队列(Queue)—面试题(二)

1. 用队列实现栈。 习题链接https://leetcode.cn/problems/implement-stack-using-queues/description/描述: 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty&a…

在 .NET 9 中使用 Scalar 替代 Swagger

前言 在.NET 9发布以后ASP.NET Core官方团队发布公告已经将Swashbuckle.AspNetCore(一个为ASP.NET Core API提供Swagger工具的项目)从ASP.NET Core Web API模板中移除,这意味着以后我们创建Web API项目的时候不会再自动生成Swagger API文档了…

双模充电桩发展前景:解锁新能源汽车未来的金钥匙,市场潜力无限

随着全球能源转型的浪潮席卷而来,新能源汽车行业正以前所未有的速度蓬勃发展,而作为其坚实后盾的充电基础设施,特别是双模充电桩,正逐渐成为推动这一变革的关键力量。本文将从多维度深入剖析双模充电桩的市场现状、显著优势、驱动…

Notepad++上NppFTP插件的安装和使用教程

一、NppFTP插件下载 图示是已经安装好了插件。 在搜索框里面搜NppFTP,一般情况下,自带的下载地址容易下载失败。这里准备了一个下载连接:Release v0.29.10 ashkulz/NppFTP GitHub 这里我下载的是x86版本 下载好后在nodepad的插件里面选择打…

Mysql--运维篇--备份和恢复(逻辑备份,mysqldump,物理备份,热备份,温备份,冷备份,二进制文件备份和恢复等)

MySQL 提供了多种备份方式,每种方式适用于不同的场景和需求。根据备份的粒度、速度、恢复时间和对数据库的影响,可以选择合适的备份策略。主要备份方式有三大类:逻辑备份(mysqldump),物理备份和二进制文件备…

在 Safari 浏览器中,快速将页面恢复到 100% 缩放(也就是默认尺寸)Command (⌘) + 0 (零)

在 Safari 浏览器中,没有一个专门的快捷键可以将页面恢复到默认的缩放比例。 但是,你可以使用以下两种方法快速将页面恢复到 100% 缩放(也就是默认尺寸): 方法一:使用快捷键 (最常用) Command (⌘) 0 (零…

LLMs之RAG:《EdgeRAG: Online-Indexed RAG for Edge Devices》翻译与解读

LLMs之RAG:《EdgeRAG: Online-Indexed RAG for Edge Devices》翻译与解读 导读:这篇论文针对在资源受限的边缘设备上部署检索增强生成 (RAG) 系统的挑战,提出了一种名为 EdgeRAG 的高效方法。EdgeRAG 通过巧妙地结合预计算、在线生成和缓存策…

探索网络安全:浅析文件上传漏洞

前言 在数字化时代,网络安全已成为我们每个人都需要关注的重要议题。无论是个人隐私保护,还是企业数据安全,网络威胁无处不在。了解网络安全的基本知识和防护措施,对我们每个人来说都至关重要。 网络安全 网络安全并非只是对网…