Что означает ".()" В Котлине?
Я видел примеры, когда функция имеет аргумент, заданный 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() }}