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

net*_*men 12 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
Run Code Online (Sandbox Code Playgroud)

但是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
Run Code Online (Sandbox Code Playgroud)

那么() -> Unit(Unit) -> Unit类型有什么区别?为什么第一版processEmpty没有编译?

hot*_*key 31

Unit实际上是一个只有一个值类型(值Unit本身;这也就是它被命名的原因Unit).它对应void于Java,但它不一样.

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

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

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

至于呼叫站点,如上所述,Unit必须通过:

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

f(Unit) // the only valid call
Run Code Online (Sandbox Code Playgroud)

虽然() -> Unit功能并不需要一个参数传递:

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

f() // valid call
Run Code Online (Sandbox Code Playgroud)


在您的示例中,类型推断发生如下:

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
Run Code Online (Sandbox Code Playgroud)
  1. map: (T) -> U = { },从而一个替代UUnit从返回{ }.
  2. 因此call应该(Unit) -> Unit.
  3. call: () -> Unit这是不一样的,以(Unit) -> Unit,如上所述.错误.