() - >之间有什么区别?单位和(单位) - >单位类型?

时间:2016-02-12 10:47:39

标签: kotlin

我有以下功能:

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没有编译?

1 个答案:

答案 0 :(得分:27)

Unit实际上是type that has exactly one value(值Unit本身;此外,这就是它被命名为Unit)的原因。它对应于Java中的void,但它不一样。

Kotlin编译器将没有声明返回值的函数视为Unit-returning functions,并且也可以省略return Unit。这就是{ }是单位返回函数的原因。

但这不适用于参数。要严格,当您使用Unit参数或(Unit) -> Unit函数变量声明函数时,必须在调用站点传递类型为Unit的参数。唯一要传递的值是Unit

没有像{ doSomething() }这样的指定参数的lambda既被视为没有参数的函数,也被视为具有单个隐式参数it的函数。您可以将{ }用作() -> Unit(Unit) -> Unit

对于呼叫站点,如上所述,必须传递Unit

val f: (Unit) -> Unit = { println("Hello") }

f(Unit) // the only valid call

() -> 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不同,如上所述。错误。