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

为何Rust不为val3引用的临时变量延长作用域?

Rust中unwrap_or(&mut 0)临时值作用域不延长的原因分析

先看问题中的代码:

fn main() {  
    let mut vec = vec![1, 2,3];  

    let val1 = vec.get(0).unwrap_or(&0);  
    println!("{val1}");  

    let val2 = match vec.get_mut(0) {  
        Some(v) => v,  
        None => &mut 0,  
    };  
    println!("{val2}");  

    let val3 = vec.get_mut(0).unwrap_or(&mut 0);
    println!("{val3}");
}

编译时val3会触发如下错误:

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:13:46
   |
13 |     let val3 = vec.get_mut(0).unwrap_or(&mut 0);
   |                                              ^ - temporary value is freed at the end of this statement
   |                                              |
   |                                              creates a temporary value which is freed while still in use
14 |     println!("{val3}");
   |               ------ borrow later used here
   |
help: consider using a `let` binding to create a longer lived value
   |
13 ~     let binding = 0;
14 ~     let val3 = vec.get_mut(0).unwrap_or(&mut binding);
   |

For more information about this error, try `rustc --explain E0716`.
error: could not compile `question` (bin "question") due to 1 previous error

三个案例的差异原因

1. val1:不可变引用的unwrap_or正常运行

vec.get(0)返回Option<&i32>,对应的unwrap_or签名是fn unwrap_or(self, default: &i32) -> &i32。由于不可变引用实现了Copy trait,传入&0时,临时值0的引用会被复制一份传入函数,最终返回的引用仍然指向这个临时值。

Rust有一条临时值作用域延长规则:当临时值的引用被直接绑定到一个变量时,临时值的生命周期会延长到该变量的生命周期结束。这里val1绑定了返回的引用,所以临时值0的生命周期被延长到val1失效,因此可以正常打印。

2. val2:match中的可变引用正常运行

match的分支直接将&mut 0返回并绑定给val2,属于直接将临时值的引用绑定到变量的场景,触发了Rust的临时值作用域延长规则。临时值0的生命周期被延长到val2的生命周期结束,所以后续打印不会报错。

3. val3:可变引用的unwrap_or报错

vec.get_mut(0)返回Option<&mut i32>,对应的unwrap_or签名是fn unwrap_or(self, default: &mut i32) -> &mut i32。可变引用没有实现Copy,传入&mut 0时,这个临时引用会被移动到unwrap_or函数内部。

虽然unwrap_or最终会返回这个传入的可变引用,但Rust无法识别返回的引用和原临时值的关联——因为引用已经被移动进函数,返回的引用相当于函数的输出,而非直接绑定临时值到val3的情况。因此临时值0的生命周期不会被延长,在当前语句结束后就会被销毁,而val3还持有它的引用,最终触发“临时值被销毁但仍被借用”的错误。

你的猜测验证

你对差异的核心判断是正确的:

  • match场景中,临时值的引用直接赋值给变量,触发作用域延长;
  • unwrap_or场景中,可变引用被移动进函数,无法触发临时值作用域延长,而不可变引用因为Copy特性,保留了和临时值的绑定关系,因此可以正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 00:38:11