我可以使用2种不同的返回类型创建相同的函数,无论我选择哪个版本,都不会出现编译错误。它是一个bug还是一些语言功能?
fun unitOrInt(): Int { return 1.let { 1 }}
fun unitOrInt(): Unit { return 1.let { 1 }}
fun unitOrInt() { return 1.let { 1 }}
1.let{1}
的类型为Int
而不是Unit
。为什么允许Unit
版本?
答案 0 :(得分:5)
let
函数是通用的,signature是inline fun <T, R> T.let(block: (T) -> R): R
。调用此函数时,编译器会从封闭上下文中推断出类型参数。
在函数的第一个声明中,编译器知道预期的调用类型是Int
,因此它将R类型参数推断为Int
,并找到匹配的值键入lambda的最后一个表达式。在第二个声明中,期望的类型是Unit
,因此编译器将R推断为Unit
并忽略lambda的最后一个表达式。在第三个声明中,没有返回类型声明,因此编译器替换Unit
并像第二个声明一样对其进行分析。
为了更好地了解发生了什么,您可以明确声明let
的类型参数:
fun unitOrInt1(): Int { return 1.let<Int, Int> { 1 }}
fun unitOrInt2(): Unit { return 1.let<Int, Unit> { 1 }}