【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: 

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

补充:常见数据竞争:

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

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

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

相关文章

贪心算法详细讲解(沉淀中)

文章目录 1. 什么是贪心算法?(贪婪鼠目寸光)经典例题1.1.1 找零问题1.1.2最小路径和1.1.3 背包问题 2.贪心算法的特点2.1 证明例1 3.学习贪心的方向心得体会 1. 什么是贪心算法?(贪婪鼠目寸光) 贪心策略&a…

【专题】2025年节日营销趋势洞察报告汇总PDF洞察(附原数据表)

原文链接: https://tecdat.cn/?p38813 在当今复杂多变且竞争激烈的消费市场环境下,节日营销已成为企业获取市场份额、提升品牌影响力的关键战略时机。我们深知深入洞察节日营销趋势对于企业决策的重要性。 本报告汇总基于对 2024 年多个关键消费节点及…

51c自动驾驶~合集46

我自己的原文哦~ https://blog.51cto.com/whaosoft/13050104 #世界模型会是L3自动驾驶的唯一解吗 三维空间占有率(3D Occupancy)预测的目的是预测三维空间中的每个体素是否被占有,如果被占有,则对应的体素将被标记。3D Semant…

Linux-----线程操作(创建)

目录 创建线程 示例&#xff1a; 创建线程 #include <pthread.h>/*** 创建一个新线程* * pthread_t *thread: 指向线程标识符的指针,线程创建成功时,用于存储新创建线程的线程标识符* const pthread_attr_t *attr: pthead_attr_t结构体,这个参数可以用来设置线程的属性…

华三S6520交换机配置console和ssh

目录 一、实验目的 二、实验设备 三、实验拓扑图 四、实验步骤 1、console用户名和密码 2、ssh用户名和密码 3.配置系统时间 一、实验目的 实现对华三 S6520 交换机的 console 本地登录和 ssh 远程登录配置,确保能够通过 console 线在本地进行管理,并使用 SSH 协议进…

Vue3组件设计模式:高可复用性组件开发实战

Vue3组件设计模式:高可复用性组件开发实战 一、前言 在Vue3中&#xff0c;组件设计和开发是非常重要的&#xff0c;它直接影响到应用的可维护性和可复用性。本文将介绍如何利用Vue3组件设计模式来开发高可复用性的组件&#xff0c;让你的组件更加灵活和易于维护。 二、单一职责…

1月13日学习

[HITCON 2017]SSRFme 直接给了源代码&#xff0c;题目名称还是ssrf&#xff0c;那么该题大概率就是SSRF的漏洞&#xff0c;进行代码审计。 <?php// 检查是否存在 HTTP_X_FORWARDED_FOR 头&#xff0c;如果存在&#xff0c;则将其拆分为数组&#xff0c;并将第一个 IP 地址…

linux RT-Preempt spin lock实现

一、spin_lock概述 Spinlock是linux内核中常用的一种互斥锁机制&#xff0c;和mutex不同&#xff0c;当无法持锁进入临界区的时候&#xff0c;当前执行线索不会阻塞&#xff0c;而是不断的自旋等待该锁释放。正因为如此&#xff0c;自旋锁也是可以用在中断上下文的。也正是因为…

设计模式-工厂模式/抽象工厂模式

工厂模式 定义 定义一个创建对象的接口&#xff0c;让子类决定实列化哪一个类&#xff0c;工厂模式使一个类的实例化延迟到其子类&#xff1b; 工厂方法模式是简单工厂模式的延伸。在工厂方法模式中&#xff0c;核心工厂类不在负责产品的创建&#xff0c;而是将具体的创建工作…

C++ 文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

计算机网络 (39)TCP的运输连接管理

前言 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的传输协议&#xff0c;它在计算机网络中扮演着至关重要的角色。TCP的运输连接管理涉及连接建立、数据传送和连接释放三个阶段。 一、TCP的连接建立 TCP的连接建立采用三次握手机制&#xff0c;其过程如下&…

机器学习(1):线性回归概念

1 线性回归基础 1.1 什么是线性 例如&#xff1a;汽车每小时60KM&#xff0c;3小时可以行使多长距离&#xff1f;已知汽车的速度&#xff0c;则汽车的行使距离只与时间唯一相关。在二元的直角坐标系中&#xff0c;描出这一关系的图是一条直线&#xff0c;所以称为线性关系。 线…

1,Linux环境变量基本定义(基于Ubuntu示例进行讲解)

linux环境变量的概念 Linux环境变量&#xff08;准确说应该是shell变量&#xff09;&#xff0c;是直接存储在操作系统中的一组键值对&#xff08;dict类型&#xff09;&#xff0c;用于配置系统和应用程序的操作行为。 【有经验的描述】&#xff1a;它们的工作原理很简单&am…

STM32入门教程-示例程序(按键控制LED光敏传感器控制蜂鸣器)

1. LED Blink&#xff08;闪烁&#xff09; 代码主体包含&#xff1a;LED.c key.c main.c delay.c&#xff08;延时防按键抖动&#xff09; 程序代码如下&#xff08;涉及RCC与GPIO两个外设&#xff09;&#xff1a; 1.使用RCC使能GPIO时钟 RCC_APB2PeriphClockC…

java springboot3.x jwt+spring security6.x实现用户登录认证

springboot3.x jwtspring security6.x实现用户登录认证 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;它用于在网络应用环境中传递声明。通常&#xff0c;JWT用于身份验证和信息交换。JWT的一个典型用法是…

基于Socket和ServerSocket自定义协议的实现多端通信、消息发送、群聊发送

通信基础 Socket Socket套接字是实现网络通信的重要接口&#xff0c;Socket绑定的应用进程&#xff0c;目标Ip的端口号&#xff0c;以及数据传输对应的输入输出缓冲区。一个数据包到达一台计算机物理设备后&#xff0c;经过网络协议栈的解析&#xff0c;然后由操作系统调度到对…

【Uniapp-Vue3】Prop校验与prop默认值用法及循环遍历数组对象

一、prop校验 如果我们在想要限制prop的类型&#xff0c;就可以在接收prop的时候对接收类型进行限制&#xff1a; defineProps({ 属性名:{ type:类型 } }) 需要注意类型的首字母大写 但是设置了传入参数类型限制并不能严格限制&#xff0c;只会在后台进行提示&#xff1a; 二、…

Java Stream流操作List全攻略:Filter、Sort、GroupBy、Average、Sum实践

在Java 8及更高版本中&#xff0c;Stream API为集合处理带来了革命性的改变。本文将深入解析如何运用Stream对List进行高效的操作&#xff0c;包括筛选&#xff08;Filter&#xff09;、排序&#xff08;Sort&#xff09;、分组&#xff08;GroupBy&#xff09;、求平均值&…

ExplaineR:集成K-means聚类算法的SHAP可解释性分析 | 可视化混淆矩阵、决策曲线、模型评估与各类SHAP图

集成K-means聚类算法的SHAP可解释性分析 加载数据集并训练机器学习模型 SHAP 分析以提取特征对预测的影响 通过混淆矩阵可视化模型性能 决策曲线分析 模型评估&#xff08;多指标和ROC曲线的目视检查&#xff09; 带注释阈值的 ROC 曲线 加载 SHAP 结果以进行下游分析 与…

【Python通过UDP协议传输视频数据】(界面识别)

提示&#xff1a;界面识别项目 前言 随着网络通信技术的发展&#xff0c;视频数据的实时传输在各种场景中得到了广泛应用。UDP&#xff08;User Datagram Protocol&#xff09;作为一种无连接的协议&#xff0c;凭借其低延迟、高效率的特性&#xff0c;在实时性要求较高的视频…