I'm getting to grips with Rust by trying to implement a singly-linked list. Here are my data structures:
struct Linked<T> {
head: Option<Box<Node<T>>>
}
struct Node<T> {
data: T,
next: Option<Box<Node<T>>>
}
Now, I'd like to add an iterator to this:
struct LinkedIter<'a, T: 'a> {
node: Option<&'a Node<T>>,
}
I've written a .iter()
method for Linked<T>
, which compiles and works fine.
impl<T> Linked<T> {
fn iter(&self) -> LinkedIter<T> {
LinkedIter { node: match self.head {
Some(ref node) => Some(&**node),
None => None
}
}
}
}
Now, this match
block is converting an Option<Box<Linked<T>>>
to an Option<&Linked<T>>
. This is exactly what the Option::map()
method is for. So I reimplemented this method, using head.as_ref()
instead of head
to avoid taking ownership of the Option
's contents in the closure.
impl<T> Linked<T> {
fn iter(&self) -> LinkedIter<T> {
LinkedIter { node:
self.head.as_ref().map(|b: &Box<Node<T>>| &**b)
}
}
}
Unfortunately, the reference created in the closure cannot be allowed to outlive the closure, because it refers to something passed into the closure as a parameter. The compiler complains (paraphrased a bit):
error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements:
first, the lifetime cannot outlive the anonymous lifetime #1 defined [in the closure]
but, the lifetime must be valid for [the lifetime of the
iter
function]so that the [
node:
] expression is assignable
How can I explain to the compiler that the reference will still be valid after the closure ends?