【Rust】04-借用、引用与切片

借用、引用与切片

学习目标

  • 理解借用解决了什么问题。
  • 区分不可变引用和可变引用。
  • 掌握字符串切片和数组切片的基本用法。

为什么需要借用

如果函数只是读取一个值,不应该夺走它的所有权。引用允许我们"借用"一个值:

rust 复制代码
fn main() {
    let name = String::from("Rust");
    print_name(&name);
    println!("{name}");
}

fn print_name(value: &String) {
    println!("{value}");
}

&name 创建了一个不可变引用。函数参数 &String 表示借用一个 String,不拥有它。

不可变引用

不可变引用允许读取,不允许修改:

rust 复制代码
fn main() {
    let text = String::from("hello");
    let len = length(&text);

    println!("{text}: {len}");
}

fn length(value: &String) -> usize {
    value.len()
}

同一时间可以有多个不可变引用:

rust 复制代码
let value = String::from("hello");
let r1 = &value;
let r2 = &value;
println!("{r1}, {r2}");

可变引用

如果需要通过引用修改值,变量本身和引用都要标记为可变:

rust 复制代码
fn main() {
    let mut text = String::from("hello");
    append_world(&mut text);

    println!("{text}");
}

fn append_world(value: &mut String) {
    value.push_str(", world");
}

同一时间只能有一个可变引用:

rust 复制代码
let mut value = String::from("hello");
let r1 = &mut value;
// let r2 = &mut value; // 编译错误
println!("{r1}");

这个规则防止数据竞争和意外修改。

引用规则

Rust 引用规则可以简化为:

  1. 可以有多个不可变引用。
  2. 或者有一个可变引用。
  3. 不可变引用和可变引用不能同时活跃。
  4. 引用不能比被引用的值活得更久。

示例:

rust 复制代码
fn main() {
    let mut value = String::from("hello");

    let r1 = &value;
    println!("{r1}");

    let r2 = &mut value;
    r2.push_str("!");
    println!("{r2}");
}

这段代码可以通过,因为 r1println! 后不再使用。Rust 的非词法生命周期分析能识别这种情况。

字符串切片

字符串切片 &str 表示字符串中的一段视图:

rust 复制代码
fn main() {
    let text = String::from("hello world");
    let hello = &text[0..5];
    let world = &text[6..11];

    println!("{hello}, {world}");
}

更常见的函数参数写法是 &str,因为它既能接收 String 的切片,也能接收字符串字面量:

rust 复制代码
fn print_text(text: &str) {
    println!("{text}");
}

fn main() {
    let owned = String::from("owned string");
    print_text(&owned);
    print_text("string literal");
}

数组切片

数组或 Vec<T> 也可以切片:

rust 复制代码
fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let middle = &numbers[1..4];

    println!("{middle:?}");
}

切片不拥有数据,只是引用连续的一段元素。

常见误区

  • &String 通常可以改成更通用的 &str
  • 可变引用不是"更强的引用",而是带有独占访问要求。
  • 字符串切片索引按字节计算,切到 UTF-8 字符中间会 panic。
  • 引用不释放数据,所有者离开作用域时才释放。

练习

  1. 写一个函数接收 &str,返回字符串长度。
  2. 写一个函数接收 &mut String,在末尾追加感叹号。
  3. 对数组 [10, 20, 30, 40, 50] 创建一个包含中间三个元素的切片并打印。

后记

2026年6月10日17点11分于上海。

相关推荐
爱写代码的阿森15 分钟前
鸿蒙三方库 | harmony-utils之KvUtil键值型数据库操作详解
数据库·华为·harmonyos·鸿蒙·huawei
马优晨17 分钟前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
Database_Cool_33 分钟前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
姜太小白1 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
窝子面2 小时前
手搓最简前后端协作-node
javascript·数据库
doiito2 小时前
【AI 应用】从“外国人味”到地道中文:kokoroi-rs v0.1.2 架构升级深度解析
ai·rust·系统设计
吳所畏惧2 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈2 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HPFBoy2 小时前
log4net 数据库存日志正确配置
数据库