困惑:这段Rust代码编译报错,为何提示借用仍被使用?
Rust 借用检查器报错分析
问题代码
struct Node { next: Option<RefCell<Box<Node>>> } impl Node { fn print_nodes(head: &Node) { let mut next = Some(head); let next2; if let Some(n) = next { match &n.next { Some(n2) => { next2 = n2.borrow(); next = Some(next2.as_ref()); }, _ => { } } } } }
编译器报错信息
src/main.rs:114:33
|
109 | let next2;
| ----- bindingnext2declared here
...
114 | next = Some(next2.as_ref());
| ^^^^^^^^^^^^^^ borrowed value does not live long enough
...
120 | }
| -
| |
|next2dropped here while still borrowed
| borrow might be used here, whennext2is dropped and runs the destructor for typeRef<'_, Box<Node>>
问题解析
你误以为next2和next同作用域就会同时销毁,但Rust的变量销毁规则是先声明的后销毁:
next先被声明,next2后声明,所以函数结束时,next2会先被销毁,之后才轮到next。- 你把
next重新赋值为next2.as_ref()的引用,这个引用依赖next2持有的Ref<Box<Node>>。当next2销毁时,它的Ref会被释放,对应的Box<Node>的借用权限被收回,但此时next还未销毁,里面的引用就变成了悬垂引用——哪怕next马上也要被销毁,Rust的借用检查器也不允许这种“短暂无效引用”存在,因为销毁顺序是明确的,引用的有效性必须持续到它不再被使用。
修复示例
正确的遍历方式应避免存储跨生命周期的引用,改用循环内临时借用:
use std::cell::RefCell; struct Node { next: Option<RefCell<Box<Node>>> } impl Node { fn print_nodes(head: &Node) { let mut current = Some(head); while let Some(node) = current { // 可在此添加节点处理逻辑,如打印信息 current = node.next.as_ref().map(|n| n.borrow().as_ref()); } } }
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

