What is a purpose of Lambda\'s with Receiver in Kotlin, while we have extension functions ?
Two functions below do the same things, however first one is more readabl
An extension function is, in a sense a function with a receiver. When you are using the lambdas with receiver, you are taking advantage of the extension functions feature of Kotlin.
A lambda is a way to define behavior similar to a regular function.
A lambda with a receiver is a way to define behavior similar to an extension function.
To understand the purpose of lambdas with receivers, consider the following example function that creates and returns a Button.
fun createButton(): Button {
val button = Button()
button.text = "Some text"
button.height = 40
button.width = 60
button.setOnClickListener(listener)
button.background = drawable
return button
}
As you can see above, you call a lot of different methods on the button object, repeating the name button in every call. This is only a small example. It would be inconvenient and wouldn't look pretty, if the expression was longer or repeated many times.
To make it more concise, pretty and more readable, we use a lambda with receriver using an extension function apply(). And refactor the above code like following:
fun createButton() = Button().apply {
text = "Some text"
height = 40
width = 60
setOnClickListener(listener)
background = drawable
}
Now the code looks more pleasing to look at. The Button() is the receiver object and you can call the methods and set properties on it.
This is useful when you are creating an instance and initializing some properties instantly. In Java, this is done using the Builder pattern. In Kotlin, you can use apply() on any object even if it doesn't support Builder pattern.
The apply() function is defined in the Kotlin standard library as following (simplified):
fun T.apply(block: T.() -> Unit): T {
block()
return this
}
You can define your own lambdas with receivers in a similar fashion.