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

Rust中str与String的生命周期疑问:两段代码编译结果为何不同?

字符串字面量与String的生命周期差异解析

先看你给出的第一个报错案例:

fn check_check() {
    let r; 
    {
        let s = String::from("s");
        r = check(&s); // 报错:s does not live long enough
    }
    println!("{}", r);
}

fn check<'a>(s: &'a str) -> &'a str {
    return s;
}

这里的s是String类型,它的堆内存由栈上的s变量持有所有权。当内部代码块结束,s被销毁,对应的堆内存也会被释放。r拿到的引用指向的是已经被回收的内存,编译器自然会报错阻止这种悬垂引用。

再看第二个能正常编译的案例:

fn check_check() {
    let r; 
    {
        let s = "a";
        r = check(&s); // 编译正常
    }
    println!("{}", r);
}

fn check<'a>(s: &'a str) -> &'a str {
    return s;
}

关键区别在于字符串字面量的生命周期是'static。像"a"这种字符串字面量,是直接被嵌入到程序的二进制文件里的,从程序启动到退出,它的内存一直存在。

这里的let s = "a";其实是创建了一个&'static str类型的引用,而不是拥有所有权的String。当你把&s传给check函数时,编译器会把生命周期参数'a推断为'static——因为s本身就是静态生命周期的引用。所以r最终持有的是一个指向静态内存的引用,就算内部代码块结束,这个引用指向的内容依然有效,编译器当然不会报错。

总结两个核心点:

  • String::from("s")是拥有所有权的动态字符串,生命周期受限于它的定义作用域,作用域结束就会被销毁。
  • 字符串字面量是&'static str,生命周期贯穿整个程序运行期,不会随作用域消失而失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:37:32