Что означает ".()" В Котлине?

Я видел примеры, когда функция имеет аргумент, заданный ClassName.() Кажется, это не функция расширения, а ClassName.Function()

.Примером является Kotterknife:

private val View.viewFinder: View.(Int) -> View?
    get() = { findViewById(it) }

Который я не совсем знаю функцию,

и MaterialDrawerKt

fun Activity.drawer(setup: DrawerBuilderKt.() -> Unit = {}): Drawer {
    val builder = DrawerBuilderKt(this)
    builder.setup()
    return builder.build()
}

Где код позволяет напрямую звонить

drawer {
    ...
}

вместо того, чтобы приводить аргументы в скобках.

Есть ли где-нибудь документация по этому вопросу?

Ответ 1

Функция, которая ничего не принимает и ничего не возвращает в Kotlin, выглядит следующим образом:

var function : () -> Unit

Хотя разница в том, что функция в вашем коде ничего не возвращает, ничего не получает, но вызывается для объекта.

Например,

class Builder (val multiplier: Int) {

    fun invokeStuff(action: (Builder.() -> Unit)) {
        this.action()
    }

    fun multiply(value: Int) : Int {
        return value * multiplier
    }
}

Здесь важно то, как мы объявили тип "действия"

action: (Builder.() -> Unit)

Это функция, которая ничего не возвращает, ничего не принимает, но вызывается для объекта типа "Строитель".

Обратитесь сюда.

Ответ 2

Ответ @Kris Roofe прояснить ситуацию. Позвольте мне добавить больше к этому.

fun Activity.drawer означает, что мы создаем имя функции расширения drawer в классе Activity. Вот почему мы можем назвать метод ящика непосредственно из класса Activity или потомка Activity класс.

Подробнее о функциях расширения здесь.

(setup: DrawerBuilderKt.() → Unit = {}) В этом утверждении мы видим мощь функций котлина высшего порядка. Небольшое вступление Высшего Функции порядка: - It is a function that takes functions as parameters, or returns a function. Итак, здесь настройка параметр является функция, которая не возвращает ничего или Unit(то же, что Void в Java). DrawerBuilderKt.() означает, что функция может быть вызвана с использованием объекта класса DrawerBuilderKt. = {} означает, что параметр setup по желанию. Таким образом, функция не принимает параметров и ничего не возвращает.

Подробнее о функциях высшего порядка здесь и здесь. Подробнее о необязательном параметре здесь.

private val View.viewFinder: View. (Int) → View? сохранить функцию в свойстве. Здесь больше информации о том же. Остальные вещи такие же, как описано выше.

Надеюсь, это поможет.

Ответ 3

Это хороший вопрос. поэтому, когда у вас есть такое утверждение: T.()

это означает, что в лямде, которую вы будете передавать, "this" (который является текущим объектом) будет иметь тип T. Давайте посмотрим, насколько легко его понять:

Допустим, у нас есть некоторый класс с функцией myFun, которая принимает лямбду, определенную следующим образом:

 class MyObject {
        fun myFun(doSomething: MyObject.()->Unit) {
            doSomething()
        }

        fun doAnotherThing() {
            Timber.d("myapp", "doing another thing")
        }
    }

чтобы вызвать эту функцию, я бы сделал это:

MyObject().myFun { doAnotherThing() }

посмотрите, как он мог использовать ссылку MyObject() в качестве "этого". это действительно вызывает this.doAnotherThing(), где это только что созданный экземпляр Myobject().

мог бы также сделать это:

MyObject().apply{myFun { doAnotherThing() }}