为何我的Rust代码借用临时Nil值可编译,与《Rust程序设计语言》描述不符?
解答
你遇到的差异核心是上下文场景不匹配 + Rust临时值生命周期延长规则两个原因共同导致的:
《Rust程序设计语言》15.4章的那段说明,对应的是用所有权类型(Box)实现Cons列表的讨论背景,和你当前用共享引用实现的版本前提不一样,同时你写的代码刚好命中了Rust的生命周期特殊规则,所以能通过编译。
具体原因分两点:
- 你代码里的
Nil是List枚举的无数据单元变体,属于编译期就能确定的常量值,默认携带'static生命周期,程序运行全程都不会被销毁,自然不存在「临时值提前销毁」的问题。 - 就算你用的是普通临时值,Rust也有临时值生命周期延长规则:当对临时值的引用直接赋值给变量/结构体字段时,临时值的生命周期会被自动延长到和引用持有者的生命周期一致,你写的
let a = Cons(10, &Nil);刚好命中了这个规则,所以不会触发借用检查错误。
你可以修改代码复现书中描述的报错场景,只要打破临时值生命周期延长的条件即可:
#[derive(Debug)] enum List<'a> { Cons(i32, &'a List<'a>), Nil, } use crate::List::{Cons, Nil}; fn main() { let a: List; { // 把Nil放到内层作用域生成,生命周期仅存在于大括号内 let temp = Nil; a = Cons(10, &temp); } // temp 在这里被销毁 println!("{:?}", a); // 这里访问a就会触发借用检查报错,和书中描述一致 }
额外补充:书中之所以说这种引用实现的Cons列表不可用,核心是它会被生命周期严格限制,你只能构造所有节点生命周期完全一致、或者都是'static的列表,根本没法实现动态生成、任意长度的链表,这也是为什么官方示例要采用Box持有所有权的实现方案。
内容的提问来源于stack exchange,提问作者sohail yunus
相关产品推荐
相关产品推荐

