我有以下功能:
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的第一个版本不能编译?
发布于 2016-02-12 19:18:42
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因此,如上所述,从{ }.
U的替代品应该是(Unit) -> Unit.
call: () -> Unit,这与U不同。Unit call应该是(Unit) -> Unit。错误。https://stackoverflow.com/questions/35360630
复制相似问题