разница между забавой в компаньонном блоке объекта и вне класса в котлине?

Я изучаю kotlin и недавно заметил интересный способ писать kotlin, но не могу это понять.

взял код, который я изучаю здесь

fun drawerImageLoader(actions: DrawerImageLoaderKt.() -> Unit): DrawerImageLoader.IDrawerImageLoader { val loaderImpl = DrawerImageLoaderKt().apply(actions).build() DrawerImageLoader.init(loaderImpl) return loaderImpl } class DrawerImageLoaderKt { ... } 

почему drawerImageLoader должен drawerImageLoader определен вне класса? почему не может быть в классе и внутри блока companion object ?

Кроме того, что означает .() в DrawerImageLoaderKt.() ?

Функция определена вне класса, чтобы предоставить какой-то завод для объектов DrawerImageLoader.IDrawerImageLoader , поэтому он не привязан к конкретным экземплярам.

Синтаксис DrawerImageLoaderKt.() Определяет Lambda with Receiver , который я описал в этом потоке: Как создать вложенные функции, такие как anko-DSL-синтаксис Kotlin

Лямбда с приемником позволяет нам вызывать методы на получателе (здесь: DrawerImageLoaderKt ) литерала функции в своем теле без каких-либо определенных квалификаторов (это то, что drawerImageLoader вызывающий drawerImageLoader ). Это очень похоже на функции расширения, где также можно получить доступ к членам объекта-получателя внутри расширения.

О, эй, это моя библиотека 🙂

Функция drawerImageLoader определяется как функция уровня пакета, так что ее можно вызывать без ее префикса (как и следовало бы делать, если это был метод экземпляра или object ). Это дает вам следующий синтаксис, когда вы его вызываете (см. Здесь код):

 override fun onCreate() { super.onCreate() drawerImageLoader { set { ... } cancel { ... } } } 

Если бы это было в обычном или сопутствующем объекте, это было бы похоже на это вместо этого, что, по моему мнению, делает менее приятный DSL:

 override fun onCreate() { super.onCreate() SomeClass.drawerImageLoader { set { ... } cancel { ... } } } 

Что касается типа его параметра, то @ s1m0nw1 уже в основном ответил на эту часть здесь , но я добавлю немного больше.

Это лямбда с приемником, который помещает вас в область DrawerBuilderKt внутри лямбды, которую вы drawerImageLoader функции drawerImageLoader . Поскольку этот класс имеет методы set , cancel и placeholder , они становятся доступными для использования внутри лямбда.

Intereting Posts