Kotlin: Выполнение функциональных параметров в теле вызывающего

fun lazyProperty(initializer: () -> Int): Int { val result: Lazy<Int> = lazy(initializer) return result.value } fun main(args: Array<String>) { // 1. val bar: Int = lazyProperty({ 1 + 1 }) // 2. val foo: Int = lazyProperty() { 42 } println("bar $bar, foo: $foo") } 

Недавно я наткнулся на синтаксис вызова функции в Kotlin, и я просто не понимаю: опция кулака понятна – это лямбда, но вторая выглядит не как обычный синтаксис вызова функции с требуемым параметром. Скобки, где обычно должны быть помещены параметры, пусты, и вместо этого параметр функции входит в тело вызывающего абонента! Как это возможно и зачем это нужно?

Это еще один правильный способ прохождения лямбда. Согласно документам :

В Kotlin существует соглашение о том, что если последний параметр функции является функцией, и вы передаете лямбда-выражение в качестве соответствующего аргумента, вы можете указать его вне круглых скобок:

 lock (lock) { sharedResource.operation() } 

Вы можете выбрать какой бы подход вы ни выбрали.

Это просто соглашение. Если последний параметр функции является функцией, вы можете передать лямбду вне круглых скобок. В вашем случае у вас есть следующие варианты:

 val bar: Int = lazyProperty({ 1 + 1 }) val bar: Int = lazyProperty() { 1 + 1 } val bar: Int = lazyProperty { 1 + 1 } 

Все три варианта одинаковы.


Если ваша функция будет иметь второй параметр (в первой позиции), чем вызовы могут выглядеть так:

 fun lazyProperty(x: Int, initializer: () -> Int): Int {...} val bar: Int = lazyProperty(7, { 1 + 1 }) val bar: Int = lazyProperty(7) { 1 + 1 } 

Если ваша функция будет иметь второй параметр (во второй позиции), то вызовы могут выглядеть так:

 fun lazyProperty(initializer: () -> Int, x: Int): Int {...} val bar: Int = lazyProperty({ 1 + 1 }, 7) 

Поэтому всегда старайтесь держать Лямбду в последнем положении вашей функции.