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

为何Rust中call3返回局部变量引用可编译,call1、call2却失败?

为何Rust中call3可编译通过,call1与call2却报"cannot return reference to temporary value"错误?

先看给出的代码示例:

struct Demo(i32);

impl Demo {
    fn new() -> Self {
        Self(22)
    }
}

// 编译错误:cannot return reference to temporary value
fn call1<'a>() -> &'a Demo {
    let a = Demo(3);
    &a
}

// 编译错误:cannot return reference to temporary value
fn call2<'a>() -> &'a Demo{
    &Demo::new()
}

// 编译成功!
fn call3<'a>() -> &'a Demo {
    &Demo(34)
}

接下来逐个分析原因:

  • call1编译失败的原因:
    函数内的局部变量a在栈上分配,函数执行完毕后栈帧销毁,a占用的内存会被释放。返回&a相当于返回指向已释放内存的悬空引用,Rust的借用检查器会直接拦截这种不安全行为,因此抛出编译错误。

  • call2编译失败的原因:
    Demo::new()创建的临时Demo实例,生命周期仅局限于当前表达式范围内。函数准备返回引用时,这个临时值已经被销毁,同样会产生悬空引用,编译器因此拒绝通过编译。

  • call3编译成功的原因:
    直接使用结构体字面量Demo(34)并取引用时,Rust编译器会触发特殊优化:由于Demo是不包含任何非静态引用的类型,编译器会自动将这个临时实例提升到静态内存区,赋予它'static生命周期(贯穿整个程序运行期间)。函数返回的&'a Demo中,生命周期参数'a会被自动推断为'static('static是所有生命周期的超集,能满足任意'a的约束),因此这个引用始终有效,不会出现悬空问题,最终可以成功编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:45:37