I'm reading how to write a linked list in rust in this website Introduction - Learning Rust With Entirely Too Many Linked Lists. Although I've asked a lifetime question in https://users.rust-lang.org/t/mutable-references-lifetimes-in-itermut/117154, I ran into a new problem which I can't figure out. In this chapter: https://rust-unofficial.github.io/too-many-lists/fourth-peek.html, the writer showed an incorrect implementation:
pub fn peek_front(&self) -> Option<&T> {
self.head.as_ref().map(|node| {
&node.borrow().elem
})
}
, which is invalid because it creates a temporary value by the node.borrow().elem
and then returns a reference to it, which means returning a value referencing data owned by the current function. The signature of borrow
is
fn borrow<'a>(&'a self) -> Ref<'a, T>
And the guide says " But as soon as we return the reference from peek
, the function is over and the Ref
goes out of scope."
But by my reckoning, the lifetime 'a
of Ref
is the same as that of node
, which in turn is the same as the self
in peek, meaning as long as the List
itself is valid, the returned reference should be valid. What's wrong with my conclusion here?
The basic structure of the code is listed below:
pub struct List<T> {
head: Link<T>,
tail: Link<T>,
}
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
struct Node<T> {
elem: T,
next: Link<T>,
prev: Link<T>,
}
impl<T> List<T> {
pub fn peek_front<'b>(&'b self) -> Option<Ref<'b, T>> {
self.head.as_ref().map(|node| {
Ref::map(node.borrow(), |node| &node.elem)
})
}
}
The correct version of peek
is also included.