不能使用 if/when 赋值返回带有推断参数的 lambda,但可以使用 if/when 块



我有一个函数,它使用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 }} }

最新更新