2016-02-12 63 views
9

我有以下功能:() - >单位和(单位) - >单位类型有什么区别?

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

+0

我发现我认为更好的方法来定义'processEmpty'函数:'fun processEmpty(t:T,call:() - > Unit)= process(t,{call()},{} )' – netimen

+0

是的,'{call()}'是一个参数(隐含'it')的正确函数,因此它可以作为'(Unit) - > Unit'传递。 – hotkey

回答

19

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{ }返回。因此call应为(Unit) -> Unit
  2. call:() -> Unit这与(Unit) -> Unit不一样,如上所述。错误。