() – >单位和(单位) – >单位类型有什么区别?

我有以下功能:

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 
  1. map: (T) -> U = { } ,因此U的替换是从{ }返回的Unit
  2. 因此call (Unit) -> Unit
  3. call: () -> Unit(Unit) -> Unit ,如上所述。 错误。