Intereting Posts
Использование @ EnableNeo4jRepositories (basePackageClasses = "myApp") в Котлине Почему я получаю android.os.TransactionTooLargeException в своем приложении для Android, написанном в Kotlin / rxJava, когда я выхожу из приложения? (OnExit / OnPause)? Ошибка компиляции во время преобразования класса RealmObject в Kotlin Почему Kotlin позволяет иметь два класса с одинаковым именем и пакетом в разных папках (например, main и androidTest)? Разделение маршрутов на несколько файлов В чем разница в двух вариантах JVM Kotlin «создать проект» в IntelliJ? Как Lazy Инициализировать с параметром в Kotlin Приложение Spring Boot: наблюдатель файловой системы для многих путей Синтаксис Carat в интерфейсах Kotlin Как обновить виджет Android Studio Kotlin Котлин очистит адаптер Как создать экземпляр анонимного интерфейса в Котлине? Как получить страну пользователя для HTTP-запроса в бэкэнд? В TornadoFX, как я могу выбрать глубоко вложенное свойство для свойства nullable ItemViewModel? Импортировать вложенные объекты / функции объекта в Котлин

Могу ли я использовать имя лямбда в качестве параметра, переданного «вне круглых скобок»?

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

val plus3: (Int,Int,Int)->Int = {a,b,c->a+b+c} println(apply3(1,2,3){a,b,c->a+b+c}) // OK println(apply3(1,2,3){plus3}) // Type mismatch. Required: Int, Found: (Int,Int,Int)->Int println(apply3(1,2,3){(plus3)}) // Type mismatch. Required: Int, Found: (Int,Int,Int)->Int println(apply3(1,2,3)plus3) // unresolved reference println(apply3(1,2,3){plus3()}) // value captured in a closure println(apply3(1,2,3){(plus3)()}) // value captured in a closure 

Что такое синтаксис для размещения имени там (вне круглых скобок)?

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

Я не знаю, почему, но в документации нет ни слова на эту тему.

Да, есть:

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

plus3 – это идентификатор, а не лямбда-выражение, поэтому вы не можете указывать его вне круглых скобок.

Тип plus3 (Int, Int, Int-> Int). То же, что и для {a, b, c-> a + b + c}. Посмотрите еще раз на сообщения, которые я получаю от компилятора Kotlin.

Вы имеете в виду сообщения об ошибках при передаче { plus3 } ? По правилам Котлина { plus3 } – это лямбда, которая игнорирует свой аргумент (если есть) и возвращает plus3 . Таким образом, правило применяется, и apply3(1,2,3){plus3} означает то же самое, что и apply3(1,2,3,{plus3}) .

Он видит plus3 как Int.

Точно наоборот: он ожидает увидеть Int как возвращаемое значение лямбда и видит plus3 который (Int,Int,Int) -> Int .

Итак, проблема здесь не в высоком философском характере, но кажется чистой синтаксической.

Это была моя точка зрения: правило чисто синтаксическое, оно применяется до того, как компилятор знает что-либо о типе или значении plus3 , и поэтому он не знает и не заботится о том, является ли это значение plus3 .

Вместо этого правило могло бы сказать:

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

в этом случае apply3(1,2,3) plus3 будет работать. Но это не так.

Размещение выражения лямбда вне круглых скобок вызова функции аналогично размещению в круглых скобках следующим образом:

 println(apply3(1, 2, 3, { a, b, c -> a + b + c })) 

Отсюда мы можем просто присвоить лямбде значение val (как вы это сделали), что приводит к:

 val plus3: (Int, Int, Int) -> Int = { a, b, c -> a + b + c } println(apply3(1, 2, 3, plus3))