【发布时间】:2016-11-30 21:59:37
【问题描述】:
我正在使用 Kotlin KBuilders 和一些 protobuffs,遇到了让我困惑的情况。
首先,我有一个函数,它接受文件名和序列化 JSON 列表并将该 JSON 反序列化为 protobuff。
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。我尝试了多种变体,有和没有 return 和 map 和 let 等等。我得到的最接近的是 Sequence Unit> 的返回类型,它失败了类型推断。
谁能解释这里发生了什么?又为什么不能推断出这种类型?
【问题讨论】:
-
你读过kotlinlang.org/docs/reference/lambdas.html 吗?在第二种情况下,地图块(lambda)中的最新表达式是返回值。在第一种情况下,您有所谓的“非本地返回”kotlinlang.org/docs/reference/…
-
如果不指定所有类型和函数,我将无法重构您的代码。发布一个指向你的代码库的链接怎么样?
-
很遗憾,我不能共享代码库。有时间我会尝试将相关代码写在一个独立的类中。
标签: kotlin type-inference