Вы передаете лямбда-выражения в другие конструкторы классов, если хотите, чтобы что-то вызывалось на другом конце, что может иметь смысл, если используется в качестве обратного вызова или если вам нужна функция, которая создает объекты снова и снова, а нестатичный.В этом случае вы сохраните лямбду для последующего обращения и будете вызывать ее при необходимости.Если вы просто передаете статический экземпляр, например, foo
в вашем коде, то нет причин для лямбды.Вы всегда должны предпочитать не использовать лямбда-выражения для конструкторов;Сценарии, в которых они полезны или необходимы, являются довольно редкими ИМО.
Что касается вашего вопроса относительно invoke
: у Kotlin есть ряд функций, которые работают "по соглашению", например, rangeTo
, equals
,contains
, compareTo
, операторы индекса, а также invoke
.Узнайте о соглашениях здесь .
Теперь, когда класс предоставляет оператор invoke
, вы можете вызывать экземпляры этого класса, как если бы они были функциями:
class InvokeMe(){
operator fun invoke(value: Int) = println("invoked with $value")
}
val obj = InvokeMe()
//both are compiled to the same code
obj(10)
obj.invoke(5)
Поскольку каждая лямбда компилируется в Function
экземпляр (см. kotlin.jvm.functions
), который поставляется с реализацией invoke
, вы можете вызывать лямбда-выражения, как показано выше, то есть, используя lambda(args)
или lambda.invoke(args)