Categories
Computers

Kotlin, please allow return from closures

Edit: After writing this, I was helped by Andrey on Twitter and now I know about the return@

The simple answer is:


sequence.flatMap {
if (it.containsKey("connnected") {
return@flatMap Observable.just(it.getBoolean("connected"))
}
return@flatMap Observable.empty()
}

Here is the original post.


Today’s kotlin frustration… trying to map a Bundle into types. E.g. if the bundle has the key “connected” get it out as a boolean. otherwise, skip the event.

so I do

sequence.flatMap {
if (it.containsKey("connnected") {
return Observable.just(it.getBoolean("connected"))
}
return Observable.empty()
}

Except, oh Kotlin, you back-stabbing-friend… closures don’t allow `return`

So I edit it…

sequence.flatMap {
if (it.containsKey("connnected") {
Observable.just(it.getBoolean("connected"))
}
Observable.empty()
}

That’s probably obviously wrong to you now, but it took me a long time to see the problem.

And the fix.


sequence.flatMap {
if (it.containsKey("connnected") {
return Observable.just(it.getBoolean("connected"))
} else {
return Observable.empty()
}
}

I don’t see why Kotlin disallows the return — and it makes this kind of error much less likely. The fact that closures evaluate to the last expression is handy for doing tiny bits of work, but I find that reactive networks in RxJava are much easier to express with blocks — and if they get more than a few lines long, you sometimes really want the ability to do an early return without introducing the nested scope of an `if` statement.