Rust 入门:搞懂核心概念“所有权”

· 5min · Paxon Qiao

Rust 入门:搞懂核心概念“所有权”

刚开始学习 Rust,你可能很快就会遇到一个绕不开的核心概念——所有权(Ownership)。它既是 Rust 最强大的特性之一,也常常是新手遇到的第一个难点。

别担心!所有权正是 Rust 能够保证内存安全,让你写出高性能、高可靠性程序的“秘密武器”。这篇文章就是为你准备的入门指南,将用最直白的方式,带你一步步搞懂所有权的基本规则、什么是“移动”(move)和“复制”(copy),以及 Rust 是如何自动管理内存的。

读完这篇,你将对 Rust 的核心设计有一个清晰的认识。

所有权

所有权

  • Rust 内存模型的核心思想:所有的值都只有一个所有者
    • 只有一个位置(通常是作用域)来负责释放每个值
    • 这是通过借用检查器来实现的
      • 如果值移动了(赋值新变量、推到 Vec、置于 Heap),其所有者也变成新的位置了
  • 有些类型不遵守这个规则
    • 如果值的类型实现了 Copy trait:重新赋值时到新内存地址时发生的事复制,而不是移动。
      • 大多数原始类型,例如整数、浮点类型等,都实现了Copy

如何实现 Copy

  • 必须可以按位(bit)来复制值。
    • 这自然就不包括:
      • 含有 non-Copy 类型的类型
      • 拥有这类资源的类型:当类型的值被丢弃时,必须被释放该资源。
  • 为什么?
    • 如果 Box 是 Copy 的,进行赋值:box1 = box2…

值的删除(丢弃,dropped)

  • 当值不再被需要,其所有者会将其删除
    • 当值不再存在于作用域内
  • 类型会递归的将其所包含的值进行删除
    • 删除一个复杂类型的变量,可能会导致很多值被删除
  • Rust 不会发生多次删除同一个值的情况(因为所有权)
  • 变量若含有对其它值(B)的引用(不拥有该值),当变量被删除时,其它的值(B)不会被删除
fn main() {
  let x1 = 42;
  let y1 = Box::new(84);
  
  {
    let z = (x1, y1); // 删除的时候先删除 x1 再删除 y1
  }
  
  let x2 = x1;
  
  //let y2 = y1; // 报错
}

值删除的顺序

  • 变量(包括函数的参数)按相反的顺序进行删除
  • 嵌套的值按照源代码的顺序进行删除
  • 备注:Rust 暂时不允许在单个值内进行自我引用

总结

总的来说,所有权是 Rust 语言的核心与基石。它就像一套内置在编译器里的规则,确保我们的程序能安全、高效地使用内存,而不需要我们手动管理,也不需要额外的垃圾回收器。

通过本文,我们了解了“一个值只有一个所有者”的原则,也看到了“移动”和“复制”的区别。掌握所有权,是学好 Rust 的关键一步。也许刚开始你会觉得它的规则有点严格,但请相信,一旦跨过这个门槛,你离写出自信、可靠的 Rust 程序就非常近了。这不仅仅是学一个新概念,更是在学习一种更安全的编程思维。

参考