Rust中直接返回current.borrow().val报错,绑定变量则正常的原因
Rust中E0597错误:为何绑定变量能解决生命周期问题?
我实现了一个接收二叉树根节点TreeNodeRef的函数,目标是返回树最底层最右侧节点的值。当直接返回current.borrow().val时,编译器抛出E0597错误:current does not live long enough;但将该值先绑定到一个let变量再返回,错误就消失了,代码能正常运行。
二叉树节点定义
/// 二叉树节点结构 #[derive(Debug, Clone)] pub struct TreeNode { val: i32, left: Option<TreeNodeRef>, right: Option<TreeNodeRef>, } type TreeNodeRef = Rc<RefCell<TreeNode>>;
原报错函数实现
/// 示例树结构: /// -1 /// / \ /// -6 -5 /// / \ \ /// -3 -4 -13 /// / \ / /// -2 6 7 /// 最底层最右侧节点值为7 pub fn bottom_right_value(root: TreeNodeRef) -> i32 { let mut current = root.clone(); let mut queue: VecDeque<TreeNodeRef> = VecDeque::new(); queue.push_back(root); while !queue.is_empty() { current = queue.pop_front().unwrap(); if let Some(left) = ¤t.borrow().left { queue.push_back(left.clone()); }; if let Some(right) = ¤t.borrow().right { queue.push_back(right.clone()); }; } current.borrow().val // 此处报错E0597 }
报错信息
error[E0597]: `current` does not live long enough --> src/lib.rs:50:5 | 37 | let mut current = root.clone(); | ----------- 绑定`current`的位置 ... 50 | current.borrow().val | ^^^^^^^^^^^^^^^^ | | | 被借用的值生命周期不足 | 此处创建了一个持有借用权限的临时对象... 51 | } | - | | | `current`在此处被销毁,但此时仍处于被借用状态 | ...当临时对象被销毁时,其`Ref<'_, TreeNode>`类型的析构函数可能会用到这个借用 | = note: 临时对象属于块末尾的表达式; 考虑让临时对象更早销毁,在块内局部变量被销毁之前 help: 例如,可以将表达式的值保存到新的局部变量`x`中,再让`x`作为块末尾的表达式 | 50 | let x = current.borrow().val; x | +++++++ +++
修改后正常运行的代码
let result = current.borrow().val; result
错误原因与解决方案解析
核心在于临时对象的生命周期和局部变量的销毁顺序:
直接返回的情况:
当你直接写current.borrow().val作为函数返回值时,current.borrow()会生成一个Ref<'_, TreeNode>临时对象(用于安全访问RefCell内部数据)。这个临时对象会一直存活到函数块结束才会被销毁。
而current作为函数内的局部变量,会在函数结尾(})处被销毁。此时Ref临时对象还持有对current的引用,就造成了“被引用的对象先于引用者销毁”的生命周期冲突,触发E0597错误。绑定变量后返回的情况:
当你用let result = current.borrow().val时,current.borrow()生成的Ref临时对象只需要存活到完成val的拷贝即可——因为i32是Copy类型,val会被直接拷贝到result中。
拷贝完成后,Ref临时对象就会被立即销毁,此时current还未被销毁,不存在引用冲突。最后返回的是独立的i32值,和current的生命周期完全无关,因此编译器不会报错。
内容的提问来源于stack exchange,提问作者Anup
相关产品推荐
相关产品推荐

