0Pricing
Learn Rust Coding · 课时

详解引用与借用

学习引用与借用,让代码的多个部分能够安全地访问数据而不取得所有权。

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

什么是引用

在 Rust 中,变量拥有自己的数据。但是,如果您需要让代码的其他部分查看甚至修改这些数据,同时又不取得所有权,该怎么办呢?

这时就要用到引用!引用类似于指向某个值的指针,但 Rust 编译器会对其施加严格的规则。

您可以把它想象成透过窗户查看某件物品,而不是拥有这件物品本身。

您的第一个引用

我们使用 & 运算符创建引用。它会创建一个不拥有值的指针。下面来看看它的实际用法:

fn print_length(s: &String) {
  println!("The length is: {}", s.len());
}

fn main() {
  let message = String::from("Hello, CoddyKit!");
  print_length(&message); // Pass a reference
  println!("Original message still here: {}", message);
}

理解借用

当您创建一个值的引用时,就表示您在借用该值。所有者仍然拥有它,但您可以暂时访问它。

  • 借用而不转让:您可以使用借来的数据。
  • 不转移所有权:原变量仍然拥有该数据,并会在离开作用域时将其丢弃。
  • 安全优先:Rust 的借用规则可以防止数据竞争等常见编程错误。

不可变借用:只读访问

默认情况下,Rust 中的引用是不可变的。这意味着您可以读取它们所指向的数据,但不能修改数据。

这是 Rust 的核心安全特性!如果代码的多个部分都只有只读访问权限,它们就不会意外干扰彼此的数据。

不可变借用实战

这里,calculate_sum 函数接收一个向量的不可变引用。它可以读取元素,但不能添加或删除元素。

fn calculate_sum(numbers: &Vec<i32>) -> i32 {
  let mut total = 0;
  for num in numbers {
    total += num;
  }
  total
}

fn main() {
  let my_numbers = vec![10, 20, 30, 40];
  let sum = calculate_sum(&my_numbers); // Immutable borrow
  println!("The sum is: {}", sum);
  println!("Original vector: {:?}", my_numbers);
}

可变借用:修改数据

有时,您需要修改借用的数据。此时可以使用可变引用,表示为 &mut。

可变引用有一条重要规则:同一时间,对于一份特定的数据,您只能拥有一个可变引用。这可以防止数据竞争并确保安全。

使用 &mut 修改数据

add_suffix 函数接收一个指向 String 的可变引用。它可以直接修改原始的 String。

fn add_suffix(text: &mut String) {
  text.push_str(" (modified)");
}

fn main() {
  let mut my_string = String::from("Original text");
  add_suffix(&mut my_string); // Mutable borrow
  println!("Modified string: {}", my_string);
}

借用的黄金法则

Rust 的编译器会在编译时强制执行这些规则,以保证内存安全:

  • 同一时间,对于一份数据,您可以拥有一个可变引用。
  • 或者,您可以同时拥有任意数量的不可变引用。
  • 存在活跃的不可变引用时,您不能拥有可变引用。
  • 引用必须始终有效(不能超过其指向数据的生命周期)。

这些规则可以防止数据竞争,并确保您的程序安全且行为可预测。

相互冲突的借用

这段代码试图同时为 my_value 创建不可变引用和可变引用,这违反了 Rust 的借用规则。它将无法通过编译。

请尝试运行它,看看编译器报出的错误!

fn main() {
  let mut my_value = 100;

  let r1 = &my_value; // Immutable reference
  let r2 = &mut my_value; // Mutable reference (problem here!)

  println!("r1: {}", r1);
  // println!("r2: {}", r2); // This line would also cause an error if uncommented
}

检查您的理解

请思考下面这段 Rust 代码:

fn process_data(data: &mut Vec<i32>) {
  data.push(4);
}

fn main() {
  let mut numbers = vec![1, 2, 3];
  let first_ref = &numbers[0]; // Line A
  process_data(&mut numbers); // Line B
  println!("First element: {}", first_ref); // Line C
}

根据 Rust 的借用规则,哪一行会导致编译时错误?

回顾:引用与借用

做得很好!您已经学习了 Rust 中引用和借用的基础知识:

  • 引用(&)让您可以访问数据而不取得其所有权。
  • 借用是创建引用、借出数据访问权限的行为。
  • 不可变引用(&)提供只读访问权限。
  • 可变引用(&mut)提供读写访问权限。
  • Rust 严格的借用规则(一个可变引用或多个不可变引用)可以防止数据竞争,并在编译时确保内存安全。

掌握这些概念对于编写安全高效的 Rust 代码至关重要!

常见问题解答

「详解引用与借用」课时是免费的吗?

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

「详解引用与借用」这节课中我会学到什么?

学习引用与借用,让代码的多个部分能够安全地访问数据而不取得所有权。 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

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

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

「详解引用与借用」课时需要多长时间?

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

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

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

此课程中的所有课时

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