Вот пошаговое объяснение:
1. Создание функции, тип приемника лямбда.
fun html(init: HTML.() -> Unit): HTML {
здесь функция html принимает параметр init
типа HTML.() -> Unit
, т. Е. Указывает, что это приемник HTML и может вызываться только с помощью реального HTML объекта. И : HTML
указывает, что функция, очевидно, возвращает HTML объект.
2. вызов init в html
html.init()
Здесь функция init () вызывается как получатель HTML реальным HTML объектом.
Достаточно формального разговора. Вот что такое получатель:
Итак, если вы помните функцию расширения, определенную как fun A.myFun(...): ReturnType {}
, в этом случае вы получите переменную this
, которая действует как был вызван экземпляр типа A.
Аналогично, лямбда-получатель выдает переменную this
внутри нее,
В конкретном примере:
class A {
fun thisCanBeCalledByAInstance() {
println("I've got called")
}
}
fun main() {
val receiver: A.() -> Unit = { // this: A
thisCanBeCalledByAInstance() // prints: I've got called
// or traditional way this.thisCanBeCalledByAInstance()
}
val a: A = A()
a.receiver()
}
Здесь Вы были в состоянии вызвать метод (функцию) из экземпляра A
, даже если это был лямбда, потому что это был получатель.
PS: Для простого языка вы можете подумать html .init () как init (html), но html не является параметром, а вместо этого работает как this
vaiable внутри лямбды
Вот почему вы смогли вызвать body()
для этого лямбда, потому что вы неявно звонили this.body()
, а this
пришел от html.init()
html объекта.