You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中为何&str与&String被视为同一值的引用?借用法则困惑

Rust借用法则困惑:不同类型引用为何冲突?

问题背景

Rust教程第4.3章提及的借用法则:

在任意给定时间,你只能拥有一个可变引用,或任意数量的不可变引用。

我编写了简化示例代码:

fn main() {
    let mut str: String = String::from("hello");
    let slice: &str = &str[0..2]; // #1
    str.clear(); // #2
    println!("{}", slice);
}

编译时出现如下错误:

error[E0502]: cannot borrow `str` as mutable because it is also borrowed as immutable
 --> src/main.rs:4:5
  |
3 |     let slice: &str = &str[0..2]; // #1
  |                        --- immutable borrow occurs here
4 |     str.clear(); // #2
  |     ^^^^^^^^^^^ mutable borrow occurs here
5 |     println!("{}", slice);
  |                    ----- immutable borrow later used here

我的困惑点:#1创建的是&str类型的不可变引用,#2是&String类型的可变引用,二者类型不同,为何会违反该法则?是否有相关原理能解释该问题?

核心解释

Rust的借用法则约束的不是引用的类型,而是这些引用指向的底层内存数据。

  • #1中的&str是从String切片而来,本质是对str这个String对象底层字符数组的不可变引用。
  • #2调用str.clear()时,clear方法需要获取&mut String类型的可变引用,而这个可变引用最终指向的是和&str完全相同的底层内存块。

借用检查器只关心「同一内存区域是否同时存在可变与不可变引用」,不管引用的具体类型是&str还是&String,只要指向同一块数据,就必须遵守借用法则。

背后的安全逻辑

如果允许这种情况,会引发严重的内存安全问题:str.clear()会清空String的底层数据,可能释放内存或修改长度,此时#1中的slice就变成了指向无效内存的悬垂引用,后续println使用它会触发未定义行为。Rust的借用检查器就是要在编译期彻底杜绝这类风险。

内容的提问来源于stack exchange,提问作者xmh0511

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:48:27