Some of the standard interfaces provided by the JRE are "Null Iterators" (sorry I don't know a better name) meaning they have the rough semantics of an iterator, except that they use a single method which returns null to indicate the last item has been returned, for example, ZipInputStream provides such an interface:
ZipInputStream(stream).use { zip ->
while (true) {
val entry = zip.getNextEntry() ?: break
if (entry.name.endsWith(".txt"))
println(entry.name)
}
}
In Kotlin it's possible to process such an interface using a combination of a while(true)
and an Elvis operator with a break (as shown above).
Is there a "cleanish" / kotlin'ish way to eliminate the while(true)
, I can think of several ways to eliminate it, however I wouldn't consider any of my ideas to be as clean as the code above.
Note: I know that ZipInputStream
has an available()
method, I am not looking for a specific solution for ZipInputStream
, instead a generic solution that will work with any interface, that only has a single method - that returns null to indicate the last item has been processed.
The lambda parameter to generateSequence
has the same semantics - returns null
when the sequence ends.
So you can do:
for (thing in generateSequence { getNextThing() }) {
// ...
}
where getNextThing
is the method that you want to call, that returns null
to indicate the end of the sequence.