我正试图通过尝试实现单链表来处理Rust。以下是我的数据结构:
struct Linked<T> {
head: Option<Box<Node<T>>>
}
struct Node<T> {
data: T,
next: Option<Box<Node<T>>>
}
现在,我想为此添加一个迭代器:
struct LinkedIter<'a, T: 'a> {
node: Option<&'a Node<T>>,
}
我为.iter()
编写了一个Linked<T>
方法,该方法可以编译并正常工作。
impl<T> Linked<T> {
fn iter(&self) -> LinkedIter<T> {
LinkedIter { node: match self.head {
Some(ref node) => Some(&**node),
None => None
}
}
}
}
现在,此match
块正在将Option<Box<Linked<T>>>
转换为Option<&Linked<T>>
。这正是Option::map()
方法的用途。因此,我使用head.as_ref()
代替head
重新实现了此方法,以避免在闭包中取得Option
内容的所有权。
impl<T> Linked<T> {
fn iter(&self) -> LinkedIter<T> {
LinkedIter { node:
self.head.as_ref().map(|b: &Box<Node<T>>| &**b)
}
}
}
不幸的是,闭包中创建的引用不能超过闭包,因为它引用了作为参数传递给闭包的东西。编译器抱怨(转述一下):
错误:由于要求冲突,无法推断借用表达式的适当生命周期:
首先,生命周期不能超过[在闭包]中定义的匿名生命#1
但是,生命周期必须对[
有效iter
函数的生命周期]以便[
node:
]表达式可分配
如何向编译器解释在闭包结束后引用仍然有效?
答案 0 :(得分:3)
这个想法是告诉编译器你在map()
中引用的引用和迭代器一样长。我得到了这样的工作:
impl<T> Linked<T> {
fn iter<'a>(&'a self) -> LinkedIter<T> {
LinkedIter { node:
self.head.as_ref().map(|b: &'a Box<Node<T>>| &**b)
}
}
}