Я использую Kotlin KBuilders с некоторыми протобафами и сталкиваюсь с ситуацией, которая меня сбивает с толку.
Для начала у меня есть функция, которая принимает имя файла и список сериализованных JSON и десериализует JSON на протобафф.
fun parseFileData(fileName: String, lines: List<String>): Data.Builder.() -> Unit = when (fileName) { SOME_FILE_NAME -> deserializeLinesToModel(lines, DataModel::class.java) .let { return { dataMeasurement = buildDataMeasurement { property1 = it.reduce { acc, n -> acc + n } measurementMsec = it.map { it.measurementMsec } } } } else -> throw UnsupportedOperationException()
Первое, что я не понял, – это то, почему мне нужно возвращение внутри блока let. Но это сработало, и я продолжил.
Позже я решил реорганизовать некоторые вещи, чтобы сделать код в другом месте проще и закончил с чем-то вроде этого:
fun parseFileData(fileName: String, factory: DataFactory): Sequence<Data.Builder.() -> Unit> = when (fileName) { SOME_FILE_NAME -> factory.getSomeFileSequence() // returns Sequence<Model> .batch(1000) // process data in batches of 1000 to reduce memory footprint and payload size .map { return { dataMeasurement = buildDataMeasurement { property1 = it.reduce { acc, n -> acc + n } measurementMsec = it.map { it.measurementMsec } } } else -> throw UnsupportedOperationException()
Таким образом, в основном, вместо обработки каждой партии в виде списка, я читаю последовательность с фабрики, выставляю ее в последовательности списков и пытаюсь сопоставить каждый список с Data.Builder.() -> Unit
. Однако на этот раз я получаю return is not allowed here
. Я пробовал несколько вариаций, с возвратом и без карты, и пусть и еще много чего. Ближайшим, к которому я пришел, является тип возврата Sequence <() -> Unit>, который не выводит вывод типа.
Может ли кто-нибудь объяснить, что здесь происходит? И почему этот тип не может быть выведен?
return
на map
lambda – нелокальное возвращение. Он пытается вернуться из ближайшей функции fun
, которая, как parseFileData
является parseFileData
.
Нелокальные возвращения допускаются только от встроенных функций, чьи лямбда-параметры встроены на сайт вызова, а расширение map
для Sequence
не является встроенной функцией.
Если вы хотите вернуть значение из самой лямбда, используйте квалифицированный return return@map ...
или полностью опустите его: тогда в результате будет возвращено последнее выражение в блоке.