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

关于Rust生命周期的疑问:字符串常量引用在变量超出作用域后仍可正常使用的原因

关于Rust生命周期的疑问:字符串常量引用在变量超出作用域后仍可正常使用的原因

嘿,你观察得特别细致!这个问题的关键确实和字符串常量的静态生命周期密切相关,咱们把这件事掰扯明白:

首先,得先搞懂Rust里字符串常量的本质——像"hello"、"world"这种用双引号直接写的字符串,并不是存储在栈上的局部临时变量,而是会被编译进程序的二进制可执行文件里。从程序启动的那一刻起,它们就被加载到内存中,直到程序完全退出才会被释放。这种贯穿整个程序运行周期的生命周期,在Rust里被标记为'static。

再看你代码里的细节(我帮你补全了合理的display函数实现):

fn main() {
    let a: &str = "hello";
    let x: &str;
    let y: &str;

    {
        let b: &str = "world";
        x = display(a, b, true);
        y = display(a, b, false);
    }

    println!("{}", x); // 正常打印
    println!("{}", y); // 正常打印
}

fn display<'a>(s1: &'a str, s2: &'a str, choose_first: bool) -> &'a str {
    if choose_first {
        s1
    } else {
        s2
    }
}

这里的变量b只是一个指向静态字符串的引用,当这个内部作用域结束时,被销毁的只是b这个引用变量本身(它在栈上占用的一小片内存),但它指向的"world"字符串本体,依然安安稳稳待在静态内存区域里,根本没被回收。

然后看display函数,它返回的引用的生命周期是输入参数中较短的那个,但因为a和b指向的都是'static的字符串,所以返回的引用自然也继承了'static生命周期。哪怕承载引用的变量b已经被销毁,返回的x和y指向的还是那个一直存在的静态字符串,所以后续打印完全没问题。

对比一下就能更清楚:如果b是一个栈上的String(比如let b = String::from("world")),那当作用域结束时,b对应的堆内存会被释放,这时候再用它的引用就会触发Rust的生命周期检查错误——但字符串常量是特殊的,它们的生命周期足够长,根本不会有这个问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 13:48:12