当前位置: 首页 > news >正文

Rust基础-part5-引用

Rust基础[part5]_引用

  • 不可变引用:通过不可变引用,可以读取变量,但是不能够修改数据。一个变量可以有多个不可变引用,但不能与可变引用共存。
  • 可变引用:通过可变引用,可以读取和修改数据。一个变量在某一时刻只能有一个可变引用,且不能与不可变引用共存。

引用规则

  • 同一时间(生命周期)内,一个变量只能有一个可变引用或多个不可变引用
    • 多个不可变引用可以共存
    • 可变引用必须是独占的(不能与其他引用共存)
  • 引用必须总是有效(Rust保证引用永远不会指向无效内存)

示例1:错误示范

pub fn reference_example() {let mut s: String = String::from("Hello");// 创建不可变引用let s1: &String = &s;// 创建可变引用(错误:此时s已有不可变引用)let s2: &mut String = &mut s;// 错误:不能创建多个可变引用let s3: &mut String = &mut s;// 错误:同一生命周期内同时使用不可变和可变引用println!("s1: {}, s2: {}", s1, s2); 
}

示例 2:正确示范

pub fn reference_example() {let mut s: String = String::from("Hello");// 第一阶段:仅使用不可变引用let s1: &String = &s;println!("s1: {}", s1); // s1在此处不再使用// 第二阶段:创建可变引用(s1已不再活跃)let s2: &mut String = &mut s;println!("s2: {}", s2);
}

切片(Slices)

数组切片

 let a = [1, 2, 3];let b = & a[0..1];let c = & a[0..=1];

字符串切片

是对字符串部分内容的引用

// 字符串引用let s = String::from("Hello, Rust!");let slice1: &str = &s[0..5]; // "Hello"let slice2: &str = &s[7..]; // "Rust!"let slice3: &str = &s[..]; // "Hello, Rust!"

悬垂引用(Dangling Reference)

生命周期核心规则:引用的生命周期必须 ≤ 被引用对象的生命周期

错误示例1:

pub fn dangling_pointer_example() {let r: &String;{let s = String::from("Hello"); // s的生命周期仅在{}内r = &s;                        // r引用s,但s即将被销毁} // s在此处被释放println!("r: {}", r); // 错误:r引用的s已不存在(悬垂引用)
}

关键点

  • s的生命周期:从创建到}结束。
  • r的生命周期:从创建到函数结束(覆盖s的生命周期)。
  • 错误原因r存活时间超过s,导致引用无效。

错误示例2:

fn get_a() -> &String { // 错误:返回局部变量的引用let s = String::from("a");&s // 函数结束后s被销毁,引用悬空
}

关键点

  • 返回引用的合法性:只能返回参数全局变量的引用,不能返回局部变量的引用。

正确示例:

生命周期注解(Lifetime Annotation)

pub fn lifetime_example() {let large = longest("a", "ab");println!("The longest string is: {}", large);// 生命周期注解:确保返回的引用与参数生命周期一致fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {if x.len() > y.len() { x } else { y }}
}

关键点

  • 'a的含义:参数xy以及返回值的引用必须至少存活到'a结束
  • 编译器检查
    1. 验证xy的实际生命周期是否满足'a
    2. 确保返回值的生命周期不超过'a
  • 实际效果:返回的引用在调用者的作用域内有效(如large的生命周期覆盖longest的调用)。

总结:避免悬垂引用的3种方式

  1. 返回所有权(如fn get_a() -> String):转移值的控制权,无需引用。
  2. 引用外部变量(如fn get_a(s: &String) -> &String):确保被引用对象生命周期足够长。
  3. 生命周期注解(如fn longest<'a>(x: &'a str) -> &'a str):明确引用的合法存活范围。

文章转载自:
http://absorbingly.hfytgp.cn
http://abri.hfytgp.cn
http://chairborne.hfytgp.cn
http://cavu.hfytgp.cn
http://caprylic.hfytgp.cn
http://caffre.hfytgp.cn
http://alabamian.hfytgp.cn
http://bicipital.hfytgp.cn
http://barbotine.hfytgp.cn
http://chemic.hfytgp.cn
http://chastity.hfytgp.cn
http://birth.hfytgp.cn
http://camelopardalis.hfytgp.cn
http://canavalin.hfytgp.cn
http://choreodrama.hfytgp.cn
http://avenge.hfytgp.cn
http://augmented.hfytgp.cn
http://amortize.hfytgp.cn
http://cheltonian.hfytgp.cn
http://abstinent.hfytgp.cn
http://biography.hfytgp.cn
http://budgie.hfytgp.cn
http://autoboat.hfytgp.cn
http://benumbed.hfytgp.cn
http://antistreptococcal.hfytgp.cn
http://antienzymic.hfytgp.cn
http://atheist.hfytgp.cn
http://adrenergic.hfytgp.cn
http://bodleian.hfytgp.cn
http://algophobia.hfytgp.cn
http://www.dtcms.com/a/280418.html

相关文章:

  • 【jvm|基本原理】第四天
  • 游戏行业中的恶梦:不断升级的DDoS攻击
  • 深入理解C++11 std::iota:从原理到实践
  • UDP和TCP的主要区别是什么
  • 17. 什么是 webSocket ?
  • 力扣 hot100 Day45
  • ZYNQ千兆光通信实战:Tri Mode Ethernet MAC深度解析
  • Keepalived双机热备概述
  • 基于深度学习的LSTM、GRU对大数据交通流量分析与预测的研究
  • omniparser v2 本地部署及制作docker镜像(20250715)
  • 从浏览器到服务器:TCP 段的网络传输之旅
  • 设计模式二:策略模式 (Strategy Pattern)
  • 云计算如何提高企业的数据安全性和隐私保护
  • 我会秘书长杨添天带队赴杭州融量农业发展有限公司考察调研
  • NQTT-基础知识
  • CSS :root伪类详解:实现动态主题切换的关键所在
  • 7.15 Java基础|大小写转换、数组、ArrayList类
  • 基于Langchain4j开发AI编程助手
  • Python_1
  • 高等数学强化——导学
  • 【Python练习】044. 编写一个函数,实现快速排序算法
  • 第十三讲 | map和set的使用
  • JavaDemo——使用CGLIB动态代理
  • I3C通信驱动开发注意事项
  • 【雅思播客016】New Year Resolution 新年决心
  • docker搭建freeswitch实现点对点视频,多人视频
  • 极致cms多语言建站|设置主站默认语言与设置后台固定语言为中文
  • 嵌入式学习-PyTorch(4)-day21
  • 多相机depth-rgb图组完整性分拣器_MATLAB实现
  • @[TOC](模拟) # 1.替换所有的问号(easy)