Need help with implementing Iter

Reference: Iteration - Learning Rust With Entirely Too Many Linked Lists

The implementation for Iter in the above link is not implemented.
Is there a way to implement it?

Literally I need only the Ref<Node<T>> as the return type of the next function, not anything else. Any help would be much appreciated.

That's not possible. The Ref needs to borrow its underlying RefCell, but that would in turn borrow the iterator itself, which is not allowed by the very signature of the Iterator trait.

The best you can do is return copies of Rc<RefCell<Node<T>>>. If you are satisfied with that, then it's actually trivial:

struct Iter<T>(Link<T>);

impl<T> Iterator for Iter<T> {
    type Item = Rc<RefCell<Node<T>>>;
    
    fn next(&mut self) -> Option<Self::Item> {
        if let Some(node) = self.0.clone() {
            self.0 = node.borrow().next.clone();
            Some(node)
        } else {
            None
        }
    }
}

kindly explain this

but this implementation, exposes both Iter as well as IterMut functionality.
since the returned Rc can be borrowed using both borrow() as well as borrow_mut() right?

I'm sorry, I don't know what specifically you don't understand about this. It follows directly from the signatures of RefCell::borrow(), Iterator::next(), and the fact that the iterator either owns or borrows from the List:

impl<T> Iterator for Iter<T> {
    type Item = Ref<'???, Node<T>>;
    
    fn next(&mut self) -> Option<Self::Item> {
        if let Some(node) = self.0.clone() {
            self.0 = node.borrow().next.clone();
            Some(node.borrow())
        } else {
            None
        }
    }
}
  1. There's no way to name the lifetime denoted by '??? above, because it must be declared in the trait itself but it only makes sense in the context of the next() method, because it should be equal to the (currently implicit) lifetime of the &mut self borrow.
  2. Even if there were a way to name it, that would violate the signature of Iterator::next(). The signature of that function is fn(&mut Self) -> Option<Self::Item>, or fn<'this>(&'this mut Self) -> Option<Self::Item> desugared. As you can see, the return type never mentions the lifetime of self, which must mean that they must be independent. Thus, any implementation that would tie the two together would be incompatible with this signature.

Yes.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.