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

为何Rust编译器判定返回的slice对s存在不可变借用?

问题:Rust中返回字符串切片的生命周期报错困惑

我正在学习Rust,修改了《Rust编程》书籍中的示例代码,代码如下:

fn first_word(s: &str) -> &str {
    "there"
}

fn main() {
    let mut s = String::from("hello world");
    let word = first_word(&s);
    s.clear();
    println!("the first word is: {}", word);
}

编译器报错:

error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
 --> src/main.rs:8:5
  |
7 |     let word = first_word(&s);
  |                           -- immutable borrow occurs here
8 |     s.clear();
  |     ^^^^^^^^^ mutable borrow occurs here
9 |     println!("the first word is: {}", word);
  |                                       ---- immutable borrow later used here

我对报错信息感到困惑:逻辑上word并未借用s,但编译器却判定word对s存在不可变借用。请问编译器是否默认返回的slice一定关联唯一参数?这是否和生命周期有关?相关的通用判定规则是什么?


回答
  • 这确实和生命周期规则直接相关。Rust编译器会默认给函数补全生命周期注解,对于fn first_word(s: &str) -> &str这类函数,会自动推断为fn first_word<'a>(s: &'a str) -> &'a str——即返回的字符串切片生命周期与输入参数的生命周期绑定。

  • 编译器的判定逻辑:这是Rust的生命周期省略规则之一,当函数只有一个输入生命周期参数时,返回值的生命周期会被默认推断为和该参数一致。这条规则是为了保证绝大多数场景下的内存安全,避免返回的引用指向已失效的内存区域。

  • 你的代码冲突原因:虽然你实际返回的是静态字符串"there"(生命周期为'static,全程有效),但编译器是基于函数签名而非内部实现做生命周期检查的。它通过签名推断返回的&str与输入s绑定,因此判定word持有s的不可变借用,后续调用s.clear()(需要可变借用)时,就触发了Rust的核心借用规则——同一时间不能同时存在不可变借用和可变借用。

  • 解决方法:如果要让编译器识别返回值与输入参数无关,可以显式指定返回值的生命周期为'static:

    fn first_word(s: &str) -> &'static str {
        "there"
    }
    

    修改后,编译器会明确返回的切片不依赖输入参数s,代码即可正常编译运行。

  • 通用生命周期省略规则总结:

    1. 每个参数中的引用都拥有独立的生命周期参数;
    2. 若函数只有一个输入生命周期参数,返回值的生命周期默认与该参数一致;
    3. 若函数是方法(包含&self或&mut self参数),返回值的生命周期默认与self一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:01:05