我已经在典型的迭代遍历实现中陷入困境 . 我得到的印象是借用检查器/掉落检查器太严格,并且当它从 RefCell
越过函数边界时无法推断借用的正确生命周期 . 我需要重复设置一个变量绑定(在这种情况下为 curr
)借用其当前内容:
use std::rc::Rc;
use std::cell::RefCell;
pub struct LinkedList<T> {
head: Option<Rc<RefCell<LinkedNode<T>>>>,
// ...
}
struct LinkedNode<T> {
value: T,
next: Option<Rc<RefCell<LinkedNode<T>>>>,
// ...
}
impl<T> LinkedList<T> {
pub fn insert(&mut self, value: T, idx: usize) -> &mut LinkedList<T> {
// ... some logic ...
// This is the traversal that fails to compile.
let mut curr = self.head.as_ref().unwrap();
for _ in 1..idx {
curr = curr.borrow().next.as_ref().unwrap()
}
// I want to use curr here.
// ...
}
}
}
编译器抱怨借用的时间不够长 .
error: borrowed value does not live long enough
curr = curr.borrow().next.as_ref().unwrap()
^~~~~~~~~~~~~
note: reference must be valid for the destruction scope surrounding expression...
} else {
let mut curr = self.head.as_ref().unwrap();
for _ in 1..idx {
curr = curr.borrow().next.as_ref().unwrap()
}
note: ...but borrowed value is only valid for the expression at 60:28
for _ in 1..idx {
curr = curr.borrow().next.as_ref().unwrap()
}
我真的很感激这个问题的 iterative solution (非递归) .
2 回答
您可以克隆
Rc
以避免终身问题:这是一个较小的复制品,我认为它显示了同样的问题:
当我读到它:
foo.borrow()
返回cell::Ref,一种智能指针 . 在这种情况下,智能指针的作用类似于&Option<i32>
.as_ref()
创建一个Option<&i32>
,其中内部引用与智能指针具有相同的生命周期 .Option
被丢弃,只产生&i32
,仍然具有智能指针的生命周期 .值得注意的是,智能指针
Ref
仅持续该语句,但代码尝试将引用返回到Ref
,这将比语句更长 .通常,解决方案是做这样的事情:
这使智能指针保持更长时间,只要
foo_borrow
(代表借用本身)存在,允许引用的生命周期有效 .在循环的情况下,你可以做的事情并不多,因为你基本上想要借用每个前一个节点,直到你到达下一个节点 .