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

关于Rust中切片场景下所有权规则违反的疑问

为什么这段Rust代码会触发E0502错误?

你对代码的核心误解有两点,我们逐一拆解:

1. 返回的&str并没有脱离原String的借用关系

你以为传给first_word的&s在函数返回后就销毁了,但实际上Rust的引用生命周期是绑定的。first_word的签名会被编译器自动推断为带生命周期标注的版本:

fn first_word<'a>(s: &'a String) -> &'a str {
    // 函数体不变
}

这意味着返回的&str(也就是word)和输入的&String共享同一个生命周期——word本质上还是对原String s的不可变借用,它的“有效时间”会延续到自己最后一次被使用的地方(也就是第20行的println!)。

2. word和clear的&mut self指向的是同一个底层对象

String的内部结构包含指向字符缓冲区的指针,word作为切片引用的就是这块缓冲区;而s.clear()调用时,clear方法需要获取&mut self——也就是对整个String的可变借用,最终操作的也是同一块缓冲区。Rust的借用规则管的是对同一个对象的借用冲突,不管你借的是整个对象还是它的一部分。

错误的本质

  • 第16行:let word = first_word(&s); 创建了对s的不可变借用,这个借用的生命周期延续到第20行word被使用完毕。
  • 第18行:s.clear(); 尝试获取s的可变借用,此时不可变借用还未失效,直接违反了Rust的核心规则:同一时间,一个对象不能同时存在可变借用和不可变借用。

修复方案

方案1:提前结束不可变借用

把println!移到clear前面,让word的使用先完成,不可变借用失效后再操作可变引用:

fn main() {
    let mut s = String::from("hello world");

    let word = first_word(&s); 
    println!("the first word is: {}", word);

    s.clear(); 
}

方案2:复制为独立的String

如果需要在clear后仍保留word的内容,可以把切片复制成新的String,彻底脱离对原对象的依赖:

fn main() {
    let mut s = String::from("hello world");

    let word = first_word(&s).to_string(); 

    s.clear(); 
    println!("the first word is: {}", word);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:35:54