Learn Rust Coding · 课时

理解 Rust 的所有权模型

掌握所有权的核心规则和移动语义,了解它们如何避免双重释放等常见内存错误。

第 1 / 3 课12 个步骤

理解 Rust 的所有权模型 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 1 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 3 节课。

什么是 Rust 所有权

Rust 的所有权系统是一组管理程序如何使用内存的规则。这是 Rust 的核心概念之一,使 Rust 无需垃圾回收器也能实现内存安全。

  • 不会出现悬空指针。
  • 不会出现重复释放错误。
  • 并发代码中不会出现数据竞争。

Rust 会在编译时检查这些规则!

栈内存与堆内存

程序使用两块主要的内存区域:栈和堆。

  • 栈:存放访问速度更快、大小固定的数据(例如整数、布尔值和大小已知的类型)。数据按顺序入栈和出栈。
  • 堆:存放访问速度较慢、大小可变的数据(例如 String、Vec)。数据由分配器申请和归还。

所有权主要管理堆上的数据,确保数据得到安全使用和清理。

规则 1:每个值都有所有者

所有权的第一条规则很简单:Rust 中的每个值都有一个称为其所有者的变量。

您可以把它想象成箱子上的标签。下面的变量 s 就是文本 "hello" 的所有者。

fn main() {
  let s = String::from("hello"); // s owns "hello"
  println!("{}", s);
}

规则 2:同一时间只能有一个所有者

第二条规则是:在任意时刻,一个值只能有一个所有者。这对于避免内存问题至关重要。

当您将一个复杂值(例如存储在堆上的 String)从一个变量赋给另一个变量时,所有权会被移动,而不是被复制。

所有权转移实战

看看将 s1 的值赋给 s2 时会发生什么。请尝试运行这段代码。

fn main() {
  let s1 = String::from("Hello, CoddyKit!");
  let s2 = s1; // Ownership of the String data moves from s1 to s2

  // println!("{}", s1); // This line would cause a compile-time error!
  println!("{}", s2);
}

理解“移动”语义

执行 let s2 = s1; 后,s1 将不再被视为有效。Rust 会阻止您再次使用 s1。

  • 这称为移动。栈上的指针、长度和容量会被复制,但堆上的数据本身不会被复制。
  • 如果 s1 仍然有效,那么当 s1 和 s2 离开作用域时,它们都会尝试释放同一块内存,从而产生重复释放错误。

Rust 的所有权系统会在编译时阻止这种情况!

所有权与函数调用

将值传递给函数的行为与将值赋给另一个变量类似:所有权会移动到函数中。

函数执行完毕后,值的所有者(函数参数)会离开作用域,该值也会被丢弃。

函数所有权演示

请观察 String 值如何移动到 takes_ownership 中,然后由 gives_ownership 返回一个新的 String。

fn takes_ownership(some_string: String) {
  println!("Inside takes_ownership: {}", some_string);
} // some_string goes out of scope and `drop` is called.

fn gives_ownership() -> String {
  let some_string = String::from("returned string");
  some_string // Ownership is moved out of the function
}

fn main() {
  let s1 = String::from("hello");
  takes_ownership(s1); // s1's value moves into takes_ownership
  // println!("{}", s1); // Error: s1 is no longer valid here!

  let s2 = gives_ownership(); // s2 gets ownership of the returned String
  println!("After gives_ownership: {}", s2);
}

规则 3:作用域与丢弃

最后一条规则是:当所有者离开作用域时,该值就会被丢弃。

  • 作用域是程序中某个项目保持有效的范围,通常由 {} 花括号定义。
  • 当变量离开作用域时,Rust 会自动调用一个名为 drop 的特殊函数。

这样可以在无需垃圾回收器的情况下,自动、安全地清理内存。

防止内存错误

所有权规则共同确保了内存安全:

  • 一个所有者:防止代码的多个部分尝试释放同一块内存。
  • 作用域结束时丢弃:确保内存只释放一次,并且在正确的时间释放。

这些规则会在编译时消除重复释放错误和释放后使用错误等常见问题,让您更加安心!

所有权检查

请思考下面的 Rust 代码。尝试编译并运行它时会发生什么?

fn main() {
  let message = String::from("Rust is fun!");
  let greeting = message;
  println!("{}", message);
}

回顾:所有权基础

做得很好!您已经学会了 Rust 所有权系统的基本规则:

  • 每个值都有一个所有者。
  • 同一时间只能有一个所有者。
  • 当所有者离开作用域时,该值会被丢弃。

无需垃圾回收器,这套系统就能防止常见的内存错误。接下来,我们将探索如何通过借用来共享数据,而不转移所有权。

免费开始

用 AI 导师学习 Rust — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
39
课程
144

常见问题解答

「理解 Rust 的所有权模型」课时是免费的吗?

是的 — 「理解 Rust 的所有权模型」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 3 节课。

「理解 Rust 的所有权模型」这节课中我会学到什么?

掌握所有权的核心规则和移动语义,了解它们如何避免双重释放等常见内存错误。 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Learn Rust Coding 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 3 节。

「理解 Rust 的所有权模型」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Learn Rust Coding 课中编写并运行代码吗?

能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 理解 Rust 的所有权模型
  2. 详解引用与借用
  3. 用于安全引用的生命周期
← 返回 Learn Rust Coding