Требуется ли для функции Kotlin Fold приведение типа или указание лямбда-типа? - PullRequest
0 голосов
/ 18 марта 2020

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

val fruits = listOf("apple", "apricot", "banana", "blueberry", "cherry", "coconut")

// collect only even length Strings
val evenFruits = fruits.groupingBy { it.first() }
    .fold(listOf<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }

println(evenFruits) // {a=[], b=[banana], c=[cherry]}

Они говорят, что в качестве аргумента должна быть только одна «функция операции».

.fold(listOf<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }

Однако, кроме лямбды, они также имеют часть (listOf<String>()). Хотя отсутствие скобок вокруг аргументов в некоторых вызовах функций иногда смущает меня, я представляю, что это не может быть вызов функции сам по себе. Требуется ли для функции Kotlin fold указание типа или указание типа лямбды? Если я избавлюсь от этого фрагмента кода, он сломается. Я был почти уверен, что единственный способ указать тип - это анонимные функции с возвращаемым типом, а не лямбда-выражения, так что я действительно не слишком уверен, что здесь происходит. Я новичок в Kotlin, поэтому любые объяснения относительно того, что означает этот синтаксис и как работает функция сгиба, будут оценены.

Вот ссылка на документацию: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold.html

1 Ответ

2 голосов
/ 18 марта 2020

В связанной документации вы можете видеть 2 аргумента:

inline fun <T, R> Iterable<T>.fold(
    initial: R,
    operation: (acc: R, T) -> R
): R

По правилу конечная лямбда вызов - это еще один способ записи

.fold(listOf<String>(), { acc, e -> if (e.length % 2 == 0) acc + e else acc })

То есть initial равно listOf<String>(), а operation равно { acc, e -> if (e.length % 2 == 0) acc + e else acc }. Причина, по которой String необходимо указать в listOf<String>(), заключается в том, что он помогает компилятору выяснить, что R равно List<String>, а затем он знает типы обоих аргументов в { acc, e -> ... }.

Если я избавлюсь от этого фрагмента кода, он сломается.

Если вы имеете в виду просто удаление (listOf<String>()), то у вас остается один аргумент, а для fold требуется два.

Требуется ли для функции Kotlin fold преобразование типов или указание лямбда-типа?

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

...