不能使用 if/when 赋值给带有推断参数的 return lambda,但可以使用 if/when 块
Can't use if/when assignment to return lambda with inferred parameter but can use if/when blocks
我有函数 return 使用 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>
格式,包括 return 类型,然后在编译或预编译时,我收到 Unresolved reference: it
错误:
fun getConversionLambda2(str: String): (Double) -> Double = when(str) {
"CelsiusToFahrenheit" -> { it * 1.8 + 32 }
"KgToPounds" -> { it * 2.204623 }
else -> { it }
}
即使我在函数块中将其指定为 return
的结果,或者先将其分配给变量然后 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
没有问题?它显然是在推断 lambda 的参数类型,并根据 getConversionLambda
定义的显式 return 类型执行单参数-it
。那么为什么不使用 when
-版本 2 和 3?我正在使用 Kotlin v1.4.32。
编辑: 似乎 if
和 when
的任何 'expression assignment' 版本都产生了这个问题 除非我明确指定 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 }} }
我有函数 return 使用 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>
格式,包括 return 类型,然后在编译或预编译时,我收到 Unresolved reference: it
错误:
fun getConversionLambda2(str: String): (Double) -> Double = when(str) {
"CelsiusToFahrenheit" -> { it * 1.8 + 32 }
"KgToPounds" -> { it * 2.204623 }
else -> { it }
}
即使我在函数块中将其指定为 return
的结果,或者先将其分配给变量然后 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
没有问题?它显然是在推断 lambda 的参数类型,并根据 getConversionLambda
定义的显式 return 类型执行单参数-it
。那么为什么不使用 when
-版本 2 和 3?我正在使用 Kotlin v1.4.32。
编辑: 似乎 if
和 when
的任何 'expression assignment' 版本都产生了这个问题 除非我明确指定 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 }} }