学习 Rust 的第七天:如何理解引用

embedded/2024/12/22 2:34:16/

大家好,

今天是我学 Rust 的第7天,今天我要来看一下引用和借用。昨天我学习了 Rust 的所有权模型,如果你对 Rust 一无所知的话,那篇文章是必读的。

引用

昨天我们看到,将参数传递给函数与将值赋给另一个变量产生了相同的效果,实际上导致了所有权的丧失。不过,有一个解决方法。
如果你了解 C 语言,指针 是 C 语言的一个重要概念。而引用与之类似。

让我们看一下代码并理解它:

rust">fn main(){  let s1: String = String::from("Hello World");  let length: usize = calculate_length(&s1); // & 用于传递字符串的引用  println!("`{}` 的长度为 {}" ,s1,length);  
}  fn calculate_length(s: &String) -> usize {  s.len()  }

Rust 中的引用是指针,允许借用和访问数据而不转移所有权,有助于内存安全,防止数据竞争。

解释:

  • fn main(): 程序的入口点。
  • let s1: String = String::from("Hello World");: 声明一个 String 变量 s1,值为 “Hello World”。
  • let length: usize = calculate_length(&s1);: 调用 calculate_length 函数,传递对字符串 s1 的引用。
  • fn calculate_length(s: &String) -> usize: 函数以对 String 的引用 (&String) 作为参数,并返回它的长度作为 usize 类型。
  • s.len(): 获取引用 s 所指向的 String 的长度。
  • println!("{} 的长度为 {}" ,s1, length);: 打印原始字符串 s1 及其长度。

关键概念:

  • & 用于传递对字符串的引用 (&s1),而不是转移所有权,防止字符串被移动或克隆。
  • 这种借用允许 calculate_length 函数在不获取所有权的情况下操作字符串。
  • 引用默认为不可变。

感谢 Let's Get Rusty 在他的 YouTube 频道上提供这么棒的解释。

可变引用

我们上面看到的是不可变引用,我们无法真正改变值,但我们可以从中读取。让我们来看看 可变引用

rust">fn main() {  let mut s1 = String::from("Hello");  // 传递可变引用给 modify_string 函数  modify_string(&mut s1);  // 原始字符串现在被修改了  println!("修改后的字符串: {}", s1);  
}  fn modify_string(s: &mut String) {  s.push_str(", World!"); // 通过追加来修改字符串  
}

解释:

  • fn main(): 程序的入口点。
  • let mut s1 = String::from("Hello");: 声明一个可变的 String 变量 s1
  • modify_string(&mut s1);: 调用 modify_string 函数,传递对 s1 的可变引用。
  • fn modify_string(s: &mut String): 函数以对 String 的可变引用 (&mut String) 作为参数。
  • s.push_str(", World!");: 通过追加将 “, World!” 添加到 s 所指向的字符串。
  • println!("修改后的字符串: {}", s1);: 打印修改后的字符串。

关键概念:

  • 可变引用可以通过 &mut 变量名 进行传递。

可变引用的规则

  • 对于特定数据片段,只允许一个可变引用或多个不可变引用。
  • 在可变引用有效时,不允许对相同数据进行其他引用。
  • 可变引用受其作用域的约束,防止悬空引用。
  • 在特定作用域内只能存在一个可变引用,以确保协调的修改。

简单来说,一个特定作用域内只能存在一个对变量的可变引用。

虽然不可变引用的数量可以是无限的。

但是,不可变和可变引用可以同时存在于相同的作用域内。

示例:

rust">fn main(){  let mut string1: String = String::from("Hello World");  let reference1: &String = &string1;  let reference2: &String = &string1;  takes_ownership(reference1);  takes_ownership(reference2);  let _mut_ref: &mut String = &mut string1;  
}  fn takes_ownership(_r1: &String){  
}

这个例子完全没问题,因为在我们创建 _mut_ref 时,reference1reference2 已经超出了作用域。

rust">// 这段代码会导致错误  
fn main(){  let mut string1: String = String::from("Hello World");  let reference1: &String = &string1;  let reference2: &String = &string1;  // 因为这一行  let _mut_ref: &mut String = &mut string1;  takes_ownership(reference1);  takes_ownership(reference2);  }  fn takes_ownership(_r1: &String){  
}

结论

学习 Rust 的旅程中,第7天探讨了引用和借用,这是内存安全的基本概念。不可变引用允许在不转移所有权的情况下读取数据,而可变引用则允许修改,但必须遵守规则以确保独占访问和防止数据


http://www.ppmy.cn/embedded/9369.html

相关文章

【任务调度】Apache DolphinScheduler快速入门

Apache DolphinScheduler基本概念 概念:分布式、去中心化、易扩展的可视化DAG工作流任务调度系统。 作用:解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用。Apache DolphinScheduler是一款开源的调度工具&#xff…

声明式事务

文章目录 1.事务分类1.传统方式解决事务2.声明式事务 2.声明式事务案例1.需求分析2.解决方案分析3.数据表创建4.编写GoodsDao.java1.编写配置文件JdbcTemplate_ioc.xml2.单元测试 5.编写GoodsService.java6.配置事务管理器JdbcTemplate_ioc.xml7.进行测试 3.debug事务管理器Dat…

大模型日报2024-04-22

大模型日报 2024-04-22 大模型资讯 Mistral与Mixtral大型语言模型对比:7B、8x7B及8x22B 摘要: 最近,IT新闻频道广泛报道了新公开的Mixtral 8x22B模型,该模型在多项基准测试中超越了ChatGPT 3.5版本,尤其在MMLU等测试中表现突出。本…

Python爬虫数据可视化分析

Python爬虫用于从网络上获取数据,数据可视化分析则是将获取的数据进行可视化展示和分析,帮助我们更好地理解数据、发现规律、做出决策。下面是一个基本的Python爬虫数据可视化分析的流程: 步骤一:数据爬取 1.选择合适的爬虫工具&a…

关于FastJson转换map集合为json字符串解析时格式出错的问题

在Java中使用Fastjson将包含Map类型key的Map集合转换为String时,如果直接使用Fastjson的JSON.toJSONString()方法,可能会因为JavaScript的安全性限制(例如对象的key必须是字符串)而在前端JavaScript解析时出现问题。 因为当 转换时…

将自己的项目上传至Git

一、安装Git 官网:Git (git-scm.com) 二、注册gitee 官网:工作台 - Gitee.com 进入“我的”出现以下界面 三、创建仓库 点击加号,新建仓库 根据自己的需求取名,描述仓库,开源还是私有,点击创建即可,点击我的即可…

Stable Diffusion XL优化终极指南

如何在自己的显卡上获得SDXL的最佳质量和性能,以及如何选择适当的优化方法和工具,这一让GenAI用户倍感困惑的问题,业内一直没有一份清晰而详尽的评测报告可供参考。直到全栈开发者Flix San出手。 在本文中,Flix介绍了相关SDXL优化…

JS stacktrace 堆内存耗尽

javascript 堆内存耗尽 问题 是 npm run dev 的时候 报错 如下 <--- JS stacktrace --->FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory在大多数情况下&#xff0c;默认情况下 Node.js 的堆内存…