Анонимные функции kotlin, определенные с использованием ключевого слова fun

avatar
user3882729
8 августа 2021 в 21:15
80
2
1

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

fun(s: String): Int { return s.toIntOrNull() ?: 0 }
Источник

Ответы (2)

avatar
mightyWOZ
9 августа 2021 в 04:23
3

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

intList.filter(fun(item: Int): Boolean { return item > 0 })
intList.filter{ it > 0 }

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


чтобы продемонстрировать это, давайте рассмотрим тривиальную лямбду, которая содержит несколько операторов return

strList.forEachIndexed { index, s ->
    when(index){
         0 -> return@forEachIndexed 
         1 -> return@forEachIndexed
         3 -> return@forEachIndexed
         else -> { Log.d("TAG", "$index -> $s")}
     }
}

здесь, если бы мы использовали return вместо return@forEachIndexed, это вернуло бы нас из внешней области видимости. для возврата из лямбды нам нужно указать метку.

Если же лямбда содержит несколько операторов return@forEachIndexed, то этот синтаксис становится очень избыточным и многословным, было бы неплохо, если бы мы могли использовать простой return без этой метки. вот тут-то и появляются анонимные функции.

при использовании анонимной функции приведенный выше код может быть записан как

strList.forEachIndexed(fun (index, string) {
    when(index){
         0 -> return  // No need to specify label, this returns from anon function not from outer scope
         1 -> return
         3 -> return
         else -> { Log.d("TAG", "$index -> $string")}
     }
})
avatar
enzo
8 августа 2021 в 21:20
2

Из та же документация:

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

ints.filter(fun(item) = item > 0)

На практике:

fun main() {
    val ints = listOf(-2, -1, 0, 1, 2)

    // As in your snippet
    println(ints.filter(fun(item: Int): Boolean { return item > 0 }))
    // Outputs [1, 2]

    // Or simply
    println(ints.filter(fun(item) = item > 0))
    // Outputs [1, 2]
}
user3882729
8 августа 2021 в 21:23
0

спасибо @enzo. Есть ли преимущество в использовании fun в этих случаях использования по сравнению с использованием лямбда? Предположительно, тогда нет вариантов использования автономных определений анонимных функций (т.е. там, где лямбда невозможна).

enzo
8 августа 2021 в 21:26
2

На самом деле есть вариант использования, но он не распространен. Из той же ссылки, которую я отправил: «В синтаксисе лямбда-выражения (...) отсутствует одна вещь — возможность указать тип возвращаемого функцией значения. В большинстве случаев в этом нет необходимости, поскольку тип возвращаемого значения может быть определен автоматически. Однако , если вам нужно указать это явно, вы можете использовать альтернативный синтаксис: анонимную функцию».

gidds
8 августа 2021 в 22:14
0

По моему опыту, анонимное развлечение встречается очень редко; как говорит Энцо, лямбда работает (и проще) почти во всех случаях. Но лучше знать на всякий случай.

mightyWOZ
9 августа 2021 в 04:33
1

Фактический вариант использования @enzo для анонимной функции - избавиться от помеченных возвратов в лямбда-выражении.