我有一个函数,它使用if
语句返回基于输入String
条件的lambda,它运行良好-使用Head First Kotlin:中的这个修改示例
fun getConversionLambda(str: String): (Double) -> Double {
if (str == "CelsiusToFahrenheit")
return { it * 1.8 + 32 }
if (str == "KgToPounds")
return { it * 2.204623 }
return { it }
}
但由于这显然是使用when
的好地方,而且我使用<function declaration> = <expression>
格式,包括返回类型,所以在编译或预编译时,我会得到一个Unresolved reference: it
错误:
fun getConversionLambda2(str: String): (Double) -> Double = when(str) {
"CelsiusToFahrenheit" -> { it * 1.8 + 32 }
"KgToPounds" -> { it * 2.204623 }
else -> { it }
}
即使我在函数块中将其指定为return
的结果,或者先将其分配给变量然后返回,我仍然会得到Unresolved reference
错误:
fun getConversionLambda3(str: String): (Double) -> Double {
return when (str) {
"CelsiusToFahrenheit" -> { it * 1.8 + 32 }
"KgToPounds" -> { it * 2.204623 }
else -> { it }
}
}
我能让它工作的唯一方法是在lambda:中指定lambda的输入变量类型
// and infers the `(Double) -> Double` return type correctly if removed
fun getConversionLambda4(str: String): (Double) -> Double = when(str) {
"CelsiusToFahrenheit" -> { x: Double -> x * 1.8 + 32 }
"KgToPounds" -> { x: Double -> x * 2.204623 }
else -> { x: Double -> x }
}
(我的main
:(
fun main(args: Array<String>) {
println("getCL: ${getConversionLambda("KgToPounds")(2.5)}")
// println("getCL2: ${getConversionLambda2("KgToPounds")(2.5)}")
// println("getCL3: ${getConversionLambda3("KgToPounds")(2.5)}")
println("getCL4: ${getConversionLambda4("KgToPounds")(2.5)}")
}
为什么if
版本的it
没有问题?很明显,这是在推断lambdas的参数类型,并基于getConversionLambda
定义的显式返回类型来执行单参数it
。那么为什么不为CCD_ 13版本2&3.我在Kotlin v1.4.32上。
编辑:似乎if
&when
会导致此问题,除非我明确指定lambda的参数类型:
// Unresolved reference: it
fun getConversionLambda1A(str: String): (Double) -> Double =
if (str == "KgToPounds") { it * 2.204623 } else { it }
// Unresolved reference: it
fun getConversionLambda1B(str: String): (Double) -> Double {
return if (str == "KgToPounds") { it * 2.204623 } else { it }
}
但这两个指定了lambda参数的版本并没有产生错误:
// works
fun getConversionLambda1Aokay(str: String) =
if (str == "KgToPounds") { x: Double -> x * 2.204623 } else { x: Double -> x }
// works
fun getConversionLambda1Bokay(str: String): (Double) -> Double {
return if (str == "KgToPounds") { x: Double -> x * 2.204623 } else { x: Double -> x }
}
问题是,当尝试引用"它";。只要加上大括号,一切都准备好了。
fun getConversionLambda1A(str: String): (Double) -> Double =
if (str == "KgToPounds") { { it * 2.204623 } } else { { it } }
fun getConversionLambda2(str: String): (Double) -> Double = when(str) {
"CelsiusToFahrenheit" -> {{ it * 1.8 + 32 }}
"KgToPounds" -> {{ it * 2.204623 }}
else -> {{ it }} }