Котлин: почему я не могу сохранить функцию в переменной? - PullRequest
0 голосов
/ 15 декабря 2018

Почему я должен использовать ссылку на функцию для сохранения функции в переменной:

fun someFunction(i: Int): Unit = println(i)
val funVal = someFunction  // Compile error!
val funVal2 = ::someFunction // Function reference works fine

Но я могу хранить лямбда-переменную напрямую:

val someLambda: (Int) -> Unit = { i: Int -> println(i) }

Ответы [ 3 ]

0 голосов
/ 15 декабря 2018

Поскольку fun someFunction(i: Int): Unit = println(i), несмотря на то, что является function, является более конкретным типом, называемым method, поэтому вам необходим синтаксис ссылки на метод.Нечто похожее происходит и в Scala тоже

Пример

fun method(value: String) = println(value)
val function: (String) -> Unit = { value -> println(value) }

val methodRef = ::method
val functionRef = function

Дополнительная литература"Словарь программистов Kotlin"

0 голосов
/ 16 декабря 2018

Ответ GhostCat совершенно правильный, но в нем отсутствует важный момент, который, я думаю, следует упомянуть, чтобы завершить его.

Синтаксис вызываемых ссылок одинаков для всех функций и свойств, но в случае свойств абсолютно необходимо отличить свойство access foo от его вызываемой ссылки ::foo.

val foo: Int = TODO()
val fooValue = foo
val fooReference = ::foo

Таким образом, хотя функции на самом деле могут получить вызываемый эталонный синтаксис только с именем функции foo (это никак не противоречит вызову функции foo() в любом случае)для единообразия функции совместно используют синтаксис вызываемой ссылки ::foo со свойствами, что, в свою очередь, требовало особой синтаксической формы вызываемых ссылок.

0 голосов
/ 15 декабря 2018

Речь идет о правильном синтаксисе.Или, точнее, о способности компилятора понимать , что вы пытаетесь сказать ему!

Когда вы смотрите на разные примеры, вы можете обнаружить, что в принятых случаях используются определенные символыкак, например, двоеточие.Это упрощает вывод того, что должен сказать код.

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

val a = b

, вы можете позволить b быть ссылкой на метод.Но что, если вы хотите вместо этого вызвать b () ?!«Лексикографическое» расстояние между b и b () довольно мало!

Таким образом, отсутствие такого синтаксиса облегчает а) анализ кода и б) затрудняет мелкие опечатки при изменении значениявашего кода!

...