Inside a Runnable
block, I want to do some "guard block", like so:
var condition: String? = null
Runnable {
if (condition == null) return
// do something
}
but compiler says "return is not allowed here"??
Inside a Runnable
block, I want to do some "guard block", like so:
var condition: String? = null
Runnable {
if (condition == null) return
// do something
}
but compiler says "return is not allowed here"??
There are two ways you can make this work:
As mentioned in the comments, you can use a "qualified return" as discussed here. That's also what IntelliJ (AndroidStudio as well I guess) suggests:
As an alternative, you can define your Runnable
as an anonymous class which enables you to use ordinary return
statements:
object: Runnable {
override fun run() {
if (condition == null) return
// do something
}
}
IntelliJ will now suggest to transform this object
to a lambda which will result in the exact same thing with a qualified return
:
Runnable {
if (condition == null) return@Runnable
// do something
}
PS: No need to feel dumb! I suppose you would have found it easily with the right wording. It's good to know what Runnable {}
is here. It's basically a lambda which is based on SAM conversion (works with Java types with a single abstract method)
To expand on s1m0nw1's answer, using return@Runnable
is correct.
@Runnable
is, in this case, defining what you return. It also works with loops, but also methods. Here's an example with loops:
fun test(){
one@for(i in 0..100){
two@for(j in 0..i){
if(j == 20){
break;//this breaks two
}
}
}
}
This example breaks the second when j == 20. If you want to break the outer loop when j is 20 (this might not be the best example, but you still get the general idea), you'd use break@one
. For loops, this only works if you explicitly declare a label.
You basically have to specify what you want to break/return/continue (depending on what you use) in some cases. Returning from a regular method, or breaking a single loop doesn't need explicit labeling, but if you use lambda, or want to break outer loops, you'd target those using [return/break/continue]@LabelMethodClassOrInterfaceName
.
In the example I added, if you want to return instead of break, you could use return@test
. However, it's slightly pointless since return
in that context implies from the method.
With this type of lambda, you're forced to use return@InterfaceName
. InterfaceName
is replaced with whatever interface you're using (in this case Runnable).
Or you could of course get IntelliJ to auto-complete it for you.