Can you return@label some value in kotlin?

Viewed 918

I just learned about labeled returns in kotlin, and wrote this code example where I have a lambda passed to with, and there's another lambda passed to forEach and I tried to return out of with inside forEach, for some reason the compiler crashes, here's the code:

fun main(args: Array<String>) : Unit {
    val l = listOf(listOf(1,2,3), listOf(4,5,6))
    val t = label@ with(l) {
        get(0).forEach {
            return@label 2
        }
    }
    println(t)
}

Should this be allowed in Kotlin at all? Is this a compiler bug?

1 Answers

Note that if you just want to return from the with you should rather use return@with instead.

So your code should rather look like:

fun main(args: Array<String>) : Unit {
  val l = listOf(listOf(1,2,3), listOf(4,5,6))
  val t = with(l) {
    get(0).forEach {
      return@with 2
    }
  }
  println(t)
}

and yes... it will return 2 then.. You could also use return@forEach if you just wanted to return from the forEach...

If you really want to use your own label instead, ensure that you place it before the opening curly brace (without space (see also Kotlin coding convention regarding lambda formatting)), e.g.:

fun main(args: Array<String>) : Unit {
  val l = listOf(listOf(1,2,3), listOf(4,5,6))
  val t = with(l) label@{
    get(0).forEach {
      return@label 2
    }
  }
  println(t)
}

Note also: if it were a for, while, or anything where continue or break can be used, then you actually place the label in front (see Kotlin reference # Break and Continue Labels), e.g.:

lambda@ for (i in 1..3) { 
  break@label
}

Finally: try to omit own labels whenever possible. Most of the time you do not really need them... and probably it already suffices to reuse existing return@labels. Check also the Kotlin coding conventions, e.g. returns in lambda

Related