https://kotlinlang.org logo
Title
j

Jonathan Ellis

06/03/2022, 3:14 PM
operator fun Body.iterator(): Iterator<Body> {
    val body = this
    return object : Iterator<Body> {
        var current: Body? = body

        override fun hasNext(): Boolean {
            return current != null
        }

        override fun next(): Body {
            val result = current!!
            current = result.getNext()
            return result
        }
    }
}
c

Chris Lee

06/03/2022, 3:15 PM
s/b
this@iterator
or similar to get you back to the enclosing method.
m

mkrussel

06/03/2022, 3:19 PM
The
next
function is throwing the wrong exception based on the contract from Java. Kotlin has no contract on what to do if
next
cannot return anything.
j

Joffrey

06/03/2022, 3:21 PM
Yeah I would suggest adapting to a
Sequence
instead, so you don't have to deal with the iterator interface yourself
Something like this:
fun Body.asSequence(): Sequence<Body> = sequence {
    var current: Body? = this@asSequence
    while(current != null) {
        yield(current)
        current = current.getNext()
    }
}
https://pl.kotl.in/Uk-KSmcQL
j

Jonathan Ellis

06/03/2022, 5:15 PM
@Joffrey thanks. the reason I like iterator is that a for loop knows how to apply the iterator operator automatically. with the sequence approach I'd have to call .asSequence explicitly right?
j

Joffrey

06/03/2022, 5:21 PM
That's right. It's a fair point. You could of course implement the
iterator()
operator with
asSequence().iterator()
but you may as well just implement it directly like you just did.
1
s

Sam

06/06/2022, 7:41 AM
There's also an
iterator { ... }
builder that works exactly like the
sequence { ... }
builder.
😯 1
j

Joffrey

06/06/2022, 8:00 AM
TIL
s

Sam

06/06/2022, 8:07 AM
It's funny that it's not more well-known! Especially since the implementation of
sequence { ... }
is just
= Sequence { iterator(block) }
.
It never seems to be mentioned in the docs. Maybe iterators just aren't cool these days 😄.
j

Joffrey

06/06/2022, 8:59 AM
To be fair I rarely use
for
loops, so I rarely implement the
iterator
operator. And mutating a list while iterating is something I haven't had to use in Kotlin at all (for years), and this was the main reason to use iterators directly
So I get the "iterators are not cool anymore" part :)