学习 Rust 的第六天:所有权问题

大家好,

欢迎来到学习 Rust 的第 6 天,过去 5 天我们学到的内容在几乎每种语言中都是一样的。所有权是 Rust 的一个独特概念。

介绍

所有权是一种独特的内存管理系统,其中每个值都有一个指定的所有者,在所有者超出范围时自动释放内存,消除了常见的与内存相关的 bug。这种所有权模型增强了系统编程中的安全性和性能。

栈和堆

大多数编程语言不要求你去关心数据存储在哪里以及如何存储,但在低级编程语言中,这会产生很大的不同。

是用于函数调用管理和局部变量的内存区域。

是程序运行时用于分配和释放内存的动态内存区域。

工作原理

在运行时,我们的程序可以访问栈和堆。栈是一个固定大小的内存,用于存储每个函数调用和变量的栈帧。堆的大小是动态的,可以存储任意数量的数据。

示例:

rust 复制代码
fn main() {  
  fn a() {  
    let z: String = String::from("Hello World");  
    b();  
  }  
  fn b() {  
    let x: u8 = 5;  
    let y: &str = "hello";  
  }  
  a();  
}

首先调用函数 A,所以我们创建了一个栈帧。String 类型的大小可以是动态的,所以我们在堆中分配一些内存并将值存储在那里。

然后调用函数 b,这里 x 是一个无符号 8 位整数,所以我们可以直接将它存储在栈内存中。现在 y 是一个字符串字面量,它将存储在可执行文件中。

所有权

所有权的规则

  • Rust 中的每个值都有一个唯一的所有者。
  • 同一时间只能有一个所有者,防止程序的多个部分同时修改数据。
  • 所有权可以通过所有权转移和通过引用借用进行转移。
  • 当所有者超出范围时,值将被丢弃。

示例:

rust 复制代码
fn main() {  
  {  // 变量在这里不是有效的,因为它还没有被声明...  
    let var: &str = "Hello"; // 从这里开始变量是有效的  
  
  } // 作用域结束,var 不再有效  
}

内存和分配

在 Rust 中,多个变量可以以不同的方式与相同的数据交互。

示例:

rust 复制代码
fn main() {  
    let x: u8 = 5;  
    let y = x;  
    println!("X = {}, Y = {}", x, y);  
}

这将把 x 的值复制给 y,所以输出是

rust 复制代码
X = 5, Y = 5

但是:

rust 复制代码
fn main() {  
    let str1: String = String::from("Hello, World!");  
    let str2: String = str1;  
}

我们可能会认为这里会发生相同的事情,但为了确保内存安全,str1 被无效化,并且字符串 Hello, World! 被移动到 str2 中。

栈和堆的示意图可能如下所示:

尽管我们有克隆字符串的功能:

rust 复制代码
fn main() {  
    let str1: String = String::from("Hello, World!");  
    let str2: String = str1.clone();  
}

所有权和函数

将变量作为参数传递给函数的效果与将其分配给另一个变量相同。函数获取了变量的所有权。

rust 复制代码
fn main() {  
  let str1: String = String::from("Hello");  
  takes_ownership(str1);  
  println!("{}", str1); // 这会导致错误  
}  
  
fn takes_ownership(some_string: String) {  
  println!("{}", some_string);  
}

这段代码会导致错误,因为我们已经把 str1 的所有权交给了 takes_ownership 函数。因此在我们尝试在第 4 行打印它时,str1 被丢弃了。

这也适用于相反的情况。就像一个函数可以获取变量的所有权一样,它也可以将变量的所有权转移给另一个变量。

示例:

rust 复制代码
fn main() {  
  let str1: String = gives_ownership();  
  println!("String 1 : {}", str1);  
}  
  
fn gives_ownership() -> String {  
  let some_string: String = String::from("Hello World");  
  some_string  
}

这段代码获取变量 some_string 并返回变量,我们将返回值存储在变量 str1 中,有效地使 str1 成为值 Hello World 的所有者。

结论

这是对所有权模型概念的基本介绍。所有权模型有一个非常陡峭的学习曲线,但它有很多优点。

明天我将深入研究引用和借用。

相关推荐
week_泽3 分钟前
第4课:为什么记忆能力如此重要 - 学习笔记_4
人工智能·笔记·学习·ai agent
week_泽1 小时前
第6课:如何管理短期记忆和长期记忆 - 学习笔记_6
人工智能·笔记·学习·ai agent
程序员泡椒1 小时前
二分查找Go版本实现
数据结构·c++·算法·leetcode·go·二分
小雨下雨的雨1 小时前
Flutter鸿蒙共赢——墨染算法:柏林噪声与鸿蒙生态中的数字水墨意境
算法·flutter·华为·交互·harmonyos·鸿蒙
map_vis_3d2 小时前
JSAPIThree 加载简单点图层学习笔记:SimplePoint 散点可视化
笔记·学习·信息可视化·mapvthree·jsapithree·simplepoint·点图层
NAGNIP7 小时前
万字长文!回归模型最全讲解!
算法·面试
西瓜堆7 小时前
提示词工程学习笔记: 工程技术行业提示词推荐
笔记·学习
知乎的哥廷根数学学派7 小时前
面向可信机械故障诊断的自适应置信度惩罚深度校准算法(Pytorch)
人工智能·pytorch·python·深度学习·算法·机器学习·矩阵
666HZ6669 小时前
数据结构2.0 线性表
c语言·数据结构·算法
实心儿儿9 小时前
Linux —— 基础开发工具5
linux·运维·算法