3

From there: https://kotlinlang.org/docs/reference/this-expressions.html#qualified

we have a code like so:

val funLit = lambda@ fun String.() {}

Run there https://pl.kotl.in/Syah1jaIN it compiles and is called without error

I thought "lambda@" was an annotation but the documentation here: https://kotlinlang.org/docs/reference/annotations.html refers to a syntax sorta like "@word", not "word@".

Sheed
  • 577
  • 4
  • 18

3 Answers3

8

It is indeed a label and is especially useful in that example as it labels an anonymous function. You use the label for qualifying references (like this).

In the following example the lambda defines an inner method nested which may want to access the this from the funLit. Since it is anonymous we need to label it, lambda is an arbitrary identifier.

fun main() {
    val funLit = lambda@ fun String.() {
        println("this:        " + this)
        println("this@lambda: " + this@lambda)

        fun String.nested() {
            println("this        in String.nested(): " + this)
            println("this@nested in String.nested(): " + this@nested)
            println("this@lambda in String.nested(): " + this@lambda)
        }

        "nested".nested()
    }
    "funLit".funLit()
}

Running it shows very clearly what this is being referred to with the qualifier.

this:        funLit
this@lambda: funLit
this        in String.nested(): nested
this@nested in String.nested(): nested
this@lambda in String.nested(): funLit

Here is a playground link: https://pl.kotl.in/SJrlUs6LE

SpencerPark
  • 3,298
  • 1
  • 15
  • 27
2

These are called labels. Consider this example. The with accepts a receiver (StringBuilder here) and a lambda with receiver (explained here). Inside that second argument, the lambda expression, this refers to the StringBuilder. So if you print(this) it's the same as the qualified print(this@with). The qualified this makes sense when you want to access outer this references like from the enclosing instance of Outer:

class Outer{
    fun someFunction() = with(StringBuilder()){
        println(this)
        println(this@with) //same as this
        println(this@Outer)
    }
}

It's also possible to set custom labels:

fun someFunction() = with(StringBuilder()) customLabel@{
    println(this@customLabel) //same as this
}
s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
1

It's not an annotation, but a label: https://kotlinlang.org/docs/reference/returns.html#break-and-continue-labels

It's commonly used in lambdas and loops, e.g. to jump out of nested loop.

Kirill Bubochkin
  • 5,868
  • 2
  • 31
  • 50