Why is it written this way (**self).next()?

When I was reading the source code of rust iterator, I saw the following writing, and I didn't understand a few points.

  1. What is the essential difference between (**self).next() and **self.next()
  2. What does self mean here?
  3. What does *self refer to? What does **self refer to?
    Can you explain it in detail?

The precedence of prefix * is lower than postfix operators, so if you want to dereference self twice and call a method on that, then you must parenthesize. **self.next() would call next and then dereference its result.

Please read the Book to find out.

5 Likes

The method like fn f(&mut self) desugars to fn f(self: &mut Self) where Self is &mut I in your case.
So the acutal method is in the form of fn f(self: &mut &mut I), showing

  • the receiver self has the type of &mut &mut I
  • *self is the type of &mut I
  • **self is the type of I
1 Like

While that works, and is the shortest way to write it, I'm not a big fan, since it makes it easy to accidentally call the wrong thing -- which I did in core, and fixed in Properly forward ByRefSized::fold to the inner iterator by scottmcm · Pull Request #100220 · rust-lang/rust (github.com).

Thus if I were writing that bit of core today (it's probably not been changed in 5+ years), I'd do it something more like https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ba8ec86ac4ddd4fcafb8c1af67831c92

pub trait MyIterator {
    type Item;
    fn my_next(&mut self) -> Option<Self::Item>;
}

impl<I: MyIterator> MyIterator for &mut I {
    type Item = I::Item;
    fn my_next(&mut self) -> Option<Self::Item> {
        I::my_next(self)
    }
}

to emphasize that I want to call I's implementation of it specifically.

3 Likes

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.