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

Rust报错`temporary value dropped while borrowed`:list与lista的差异疑问

Rust临时值生命周期差异问题解析

问题背景

我编写了如下Rust代码:

enum List<'a> {
    Cons(i32, Box<&'a List<'a>>),
    Nil,
};
let list= Cons(10, Box::new(&Nil));
let lista = Cons(5, Box::new(&Cons(10, Box::new(&Nil))));
match lista {
    Cons(x,_) => println!("{}",x),
    Nil => ()
}

运行后编译器报错:

21 |     let lista = Cons(5, Box::new(&Cons(10, Box::new(&Nil))));
   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^  - temporary value is freed at the end of this statement 
   |                                   |
   |                                   creates a temporary which is freed while still in use

我理解Cons(10, Box::new(&Nil))会被释放导致报错,但当我将match的对象改为list时:

match list {
    Cons(x,_) => println!("{}",x),
    Nil => ()
}

代码却能正常运行,我认为Nil同样是临时值会在语句结束时被释放,请问list和lista之间的差异是什么?

核心差异解析

1. Nil是静态生命周期的全局实例

Nil是枚举的无数据变体,它不包含任何动态分配的数据或引用。在Rust中,这类无数据的枚举变体默认拥有'static生命周期——它会永久存在于程序运行期间,不会被当作临时栈值释放。

当你写&Nil时,引用指向的是一个全局静态的Nil实例,而非临时创建的栈上值。因此list里的Box::new(&Nil)保存的是指向静态Nil的引用,不存在生命周期不匹配的问题。

2. Cons(10, Box::new(&Nil))是临时栈值

lista中的Cons(10, Box::new(&Nil))是一个临时创建的Cons实例,它被分配在栈上,仅在当前语句的范围内有效。当你取它的引用&Cons(...)并放入Box时,这个引用的生命周期只到当前语句结束。但lista本身会存活到后续的match语句,这就导致引用指向的临时值已经被释放,而lista还在持有这个引用——直接触发Rust的生命周期检查错误。

3. 生命周期推导的本质区别

  • 对于list:Box<&'a List<'a>>中的引用指向'static的Nil,编译器会自动将'a推导为'static,和list的生命周期完全兼容。
  • 对于lista:内部临时Cons值的生命周期远短于lista的生命周期,不存在一个能同时覆盖两者的有效生命周期'a,因此编译器拒绝通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:25:47