Receiver functions

Kotlin has built-in language features for creating custom DSLs. Receiver functions and the Infix keyword (covered in the next section) are two of those features.

Although intended primarily for creating DSLs, receiver functions can be also useful in everyday programming and as we shall see later, the Kotlin standard library uses them in several utility functions.

We could say that receiver functions share some similarities with extension functions. They have the same syntax for marking the receiver and, inside the function, they can access members of the receiver instance. Here's how we'd define a receiver function type:

val hello: String.() -> Unit = { print("Hello $this") }

It's the same as a normal function type definition, with the addition of the receiver type and a dot before the function signature.

To call this function, we have to provide an instance of the receiver type, a string in our case:

hello("Kotlin") // prints Hello Kotlin

You can see how, inside the receiver function body, we have access to the instance of the receiver type with this keyword.

Now, let’s see an example that shows a more real-world usage scenario. Let's write a function for building a string; it accepts a receiver function with StringBuilder as the receiver type:

fun buildString(init: StringBuilder.() -> Unit): String {
val builder = StringBuilder()
init(builder)
return builder.toString()
}

We create the StringBuilder instance inside the function, apply the receiver function to it, and then build the resultant string. This enables us to create a string object like this:

val string = buildString {
append("Hello Receiver Functions")
appendln("We have access to StringBuilder object inside this lambda")
}

Notice how, inside the lambda, we are accessing members of the StringBuilder type.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.179.239