() – >单位和(单位) – >单位类型有什么区别?
我有以下功能:
fun <T, U> process(t: T, call: (U) -> Unit, map: (T) -> U) = call(map(t)) fun <T> processEmpty(t: T, call: () -> Unit) = process(t, call, {}) // error
但processEmpty
不是编译。 错误消息是Type mismatch: inferred type is () -> kotlin.Unit but (kotlin.Unit) -> kotlin.Unit was expected
。 但是,如果我改变这个功能
fun <T> processEmpty2(t: T, call: (Unit) -> Unit) = process(t, call, {}) // OK
那么() -> Unit
和(Unit) -> Unit
类型有什么区别? 为什么processEmpty
第一个版本不能编译?
Unit
实际上是一个只有一个值的类型 (值是Unit
本身;这也是它被命名为Unit
)。 它对应于Java中的void
,但不一样。
Kotlin编译器将没有声明返回值的函数作为Unit
返回函数处理 , return Unit
也可以省略。 这就是为什么{ }
是单元返回函数。
但是这不适用于论据。 严格来说,当你使用Unit
参数或者(Unit) -> Unit
函数变量来声明一个函数的时候,你必须在调用站点传递一个Unit
类型的参数。 唯一通过的价值是Unit
。
一个没有像{ doSomething() }
这样的指定参数的lambda被视为一个没有参数的函数,也是一个带有单个隐式参数的函数。 您可以使用{ }
作为() -> Unit
和(Unit) -> Unit
。
至于呼叫地点,如上所述, Unit
必须通过:
val f: (Unit) -> Unit = { println("Hello") } f(Unit) // the only valid call
Whereas () -> Unit
函数不需要传递参数:
val f: () -> Unit = { println("Hello") } f() // valid call
在你的例子中,类型推断发生如下:
fun <T, U> process(t: T, call: (U) -> Unit, map: (T) -> U) = call(map(t)) fun <T> processEmpty(t: T, call: () -> Unit) = process(t, call, {}) // error
-
map: (T) -> U = { }
,因此U
的替换是从{ }
返回的Unit
。 - 因此
call
(Unit) -> Unit
。 -
call: () -> Unit
与(Unit) -> Unit
,如上所述。 错误。