6

I'm looking at this Kotlin object declaration:

object A : B({
    variableName1 = "text1"
    variableName2 = "text2"

    params {
        param("Foo", "Bar")
    }
})

And I cannot figure out what the argument to class B's constructor is.

I have purposefully abstracted away information in this example but class B is actually

jetbrains.buildServer.configs.kotlin.v10.BuildType

And I cannot find the documentation for the type. I have found something that was close but it's a definition for an interface and thus doesn't have a constructor.

To summarise, what is this the following construct in Kotlin?

{
    variableName1 = "text1"
    variableName2 = "text2"

    params {
        param("Foo", "Bar")
    }
}
s1m0nw1
  • 67,502
  • 14
  • 150
  • 189
ZoSal
  • 531
  • 4
  • 20
  • 3
    https://confluence.jetbrains.com/display/TCD10/Kotlin+DSL – Yoav Sternberg Oct 12 '17 at 09:13
  • 1
    @YoavSternberg This is what I was looking at and got puzzled with. I may have just missed the phrase that said the argument was a function literal with receiver. – ZoSal Oct 12 '17 at 09:18

2 Answers2

10

This construct is called "Lambda with Receiver", aka "Function Literal with Receiver", which you'll find used in Kotlin DSL implementations extensively. For an example, have a look at the HTML builder DSL.

I described the whole concept in detail in this thread.

s1m0nw1
  • 67,502
  • 14
  • 150
  • 189
0

An example to try to explain function literal / lambda with receiver type:

data class Person(val name: String)

fun getPrefixSafely(
    prefixLength: Int,
    person: Person?,
    getPrefix: Person.(Int) -> String): String
{
    if (person?.name?.length ?: 0 < prefixLength) return ""
    return person?.getPrefix(prefixLength).orEmpty()
}

// Here is how getPrefixSafely can be called
getPrefixSafely(
    prefixLength = 2,
    person = Person("name"),
    getPrefix = { x -> this.name.take(x) }
)

PS: These lambdas with receiver types are similar to extension functions IMO.

Amit Dash
  • 494
  • 6
  • 19