长安的 Rust 入门教程长安的 Rust 入门教程
首页
基础教程
进阶内容
Rust 官网
编程指南
首页
基础教程
进阶内容
Rust 官网
编程指南
  • 基础教程

    • 📚 基础教程
    • 第1章 - 认识 Rust
    • 第2章 - 安装 Rust
    • 第3章 - Hello World
    • 第4章 - 变量与可变性
    • 第5章 - 数据类型
    • /guide/06-functions.html
    • 第7章 - 控制流
    • 第8章 - 所有权
    • 第9章 - 引用与借用
    • 第10章 - 结构体
    • 第11章 - 枚举
    • 第12章 - 模式匹配
    • 第13章 - 错误处理
    • 第14章 - 集合类型
    • 第15章 - 模块系统
  • 实战项目

    • 第16章 - 实战项目:猜数字游戏
    • 第17章 - 实战项目:待办事项 CLI
    • 第18章 - 实战项目:简单 HTTP 服务器

第9章 - 引用与借用

嗨,朋友!我是长安。

上一章我们学习了所有权,发现每次传递值都会转移所有权,很不方便。这一章我们学习引用(Reference)和借用(Borrowing),让你可以使用值而不获取所有权。

🔗 什么是引用?

引用就像是值的"临时通行证",你可以使用值,但不拥有它。

fn main() {
    let s1 = String::from("hello");
    
    let len = calculate_length(&s1);  // 传递引用,不转移所有权
    
    println!("字符串 '{}' 的长度是 {}", s1, len);  // s1 依然有效!
}

fn calculate_length(s: &String) -> usize {
    s.len()
}  // s 离开作用域,但因为它不拥有数据,所以什么都不会发生

使用 & 创建引用,这个过程叫做借用(borrowing)。

长安说

引用就像借书:你可以读书(使用值),但书的所有权还是属于图书馆(原变量)。读完了要还回去!

🔒 不可变引用

默认情况下,引用是不可变的:

fn main() {
    let s = String::from("hello");
    
    change(&s);  // ❌ 编译错误
}

fn change(some_string: &String) {
    some_string.push_str(", world");  // 不能修改借用的值
}

🔓 可变引用

如果需要修改借用的值,使用可变引用 &mut:

fn main() {
    let mut s = String::from("hello");
    
    change(&mut s);
    
    println!("{}", s);  // 输出:hello, world
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

⚠️ 借用规则

Rust 有严格的借用规则:

  1. 在同一时间,你只能拥有以下之一:

    • 一个可变引用
    • 任意数量的不可变引用
  2. 引用必须总是有效的

fn main() {
    let mut s = String::from("hello");
    
    let r1 = &s;      // ✅ 不可变引用
    let r2 = &s;      // ✅ 再来一个不可变引用
    println!("{} and {}", r1, r2);
    
    let r3 = &mut s;  // ✅ 可变引用(r1 和 r2 已经不再使用)
    println!("{}", r3);
}

但这样不行:

fn main() {
    let mut s = String::from("hello");
    
    let r1 = &s;      // 不可变引用
    let r2 = &mut s;  // ❌ 错误!不能在有不可变引用时创建可变引用
    
    println!("{}, {}", r1, r2);
}

长安说

为什么有这个规则?

想象你在读一本书(不可变引用),突然有人修改了这本书的内容(可变引用),你读到的信息就不一致了!Rust 通过借用规则防止这种情况。

💡 小结

  • 使用 & 创建引用(借用)
  • 引用让你使用值而不获取所有权
  • 默认引用是不可变的
  • 使用 &mut 创建可变引用
  • 同一时间只能有一个可变引用,或多个不可变引用

🚀 下一步

第10章 - 结构体 →

最近更新: 2025/12/26 18:01
Contributors: 王长安
Prev
第8章 - 所有权
Next
第10章 - 结构体