liveBook · Manning

Extension function type

As explained in Kotlin in Action, 2E

An extension function type is a Kotlin function type that specifies a receiver type before the parameter types, allowing values of that type to invoke the callable using extension-function syntax.

An extension function type gives a function a receiver type. Write StringBuilder.() -> Unit instead of (StringBuilder) -> Unit: the receiver moves before the parentheses, and the lambda can access its members without an explicit qualifier. section 13.2.1

Building a string with a receiver

fun buildString(builderAction: StringBuilder.() -> Unit): String { val sb = StringBuilder() sb.builderAction() return sb.toString() } val result = buildString { append("Hello, ") append("World!") } Here, sb supplies the receiver. Inside the lambda, it becomes the implicit this, so append() replaces the regular function-style call builderAction(sb). Explicit this.append(...) remains available for disambiguation. section 13.2.1

Listing 13.2 Redefining buildString to take a lambda with a receiver
fun buildString(
    builderAction: StringBuilder.() -> Unit   #1
): String {
    val sb = StringBuilder()
    sb.builderAction()                        #2
    return sb.toString()
}
 
fun main() {
    val s = buildString {
        this.append("Hello, ")                #3
        append("World!")                      #4
    }
    println(s)
    // Hello, World!
}

Inspect the complete receiver-based buildString example, including its declaration, invocation, and resulting output. section 13.2.1

A receiver lambda can also be stored in a variable such as val appendExcl: StringBuilder.() -> Unit. Calling stringBuilder.appendExcl() supplies the receiver, while buildString(appendExcl) passes the same callable as a builder action. section 13.2.1

Extension function types underpin lambdas with receivers and Kotlin internal DSLs, where nested receivers make multi-call APIs more expressive and reusable. section 13.5

How Kotlin in Action, 2E covers it

How deep it goes
Explains receiver-type syntax, implicit this, invocation, stored lambdas, and generic apply and with patterns.
Examples
Demonstrates buildString, a stored StringBuilder receiver lambda, and generic apply and with usage.
What it assumes
Assumes familiarity with Kotlin lambdas and function types while teaching receiver syntax from the regular function-type form.
What you can do after
Builds receiver-based Kotlin APIs and invokes receiver lambdas using extension-function syntax.
How it connects
Connects function types with extension functions, lambdas with receivers, implicit receivers, and internal DSLs.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.