Receivers in Function Types
Earlier in the book, we saw the apply()
scope function:
class SomethingOrAnother {
var someProperty = 123
}
val foo = SomethingOrAnother().apply {
someProperty = 456
}
In the lambda expression that we pass to apply()
, the value of this
is whatever we call apply()
upon. with()
works similarly, except that this
is whatever we pass as the parameter to with()
:
class SomethingOrAnother {
var someProperty = 123
}
fun main() {
val foo = SomethingOrAnother()
with(foo) {
someProperty = 456
}
}
You might think that this is some sort of compiler magic. In a sense, perhaps it is. However, both apply()
and with()
are functions implemented in Kotlin itself, and you can use this approach to tailor this
in some context of your own.
What with()
Looks Like
with()
is a very simple inline
function:
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
It takes two parameters, receiver
and block
. receiver
is just an ordinary parameter, albeit one declared using a generic type T
. block
is where the fun lies.
with()
uses two generic types: T
and R
. T
is the type for the receiver
parameter, and R
is what with()
returns.
block
is declared as T.() -> R
. () -> R
is a declaration of a function type. T.() -> R
is a declaration of an extension function type, where we need to associate any call of that function type with something of type T
.
with()
invokes block
via receiver.block()
. The combination of T.() -> R
syntax and receiver.block()
says that this
, in the context of the invoked block
, is receiver
.
If we go back to the with()
example from earlier in this chapter:
class SomethingOrAnother {
var someProperty = 123
}
fun main() {
val foo = SomethingOrAnother()
with(foo) {
someProperty = 456
}
}
receiver
in this case is our SomethingOrAnother
instance (foo
). block
is our lambda expresion ({ someProperty = 456 }
). Given how with()
is implemented, this
in that lambda expression is the SomethingOrAnother
instance, which is why we can manipulate someProperty
without specifying that object directly.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.