任何λcodomain升级为`Unit`?

时间:2018-01-30 10:55:32

标签: kotlin subtyping

显然,类型检查器拒绝了这一点:

val a: Unit = 42 // Fail

然而,这很好:

val b: Unit = { 42 }() // Pass

我能理解:

val f: ()->Any = { -> 42 } // Pass

Int <: Any以来。但是,它必须与Unit不同(它不是Int的超类型)。是否有一些文件解释了发生了什么?

2 个答案:

答案 0 :(得分:4)

官方文档涵盖了lambda expression syntax

  

如果lambda的推断返回类型不是Unit,则将lambda主体内的最后一个(或可能是单个)表达式视为返回值。

所以基本上,如果你明确地将lambda分配给一个返回Unit的函数类型,或者你调用它并将其结果分配给Unit,那么它将推断你不希望返回lambda中的最后一个表达式(默认情况下会发生这种情况)。

答案 1 :(得分:4)

val b: Unit = { 42 }() 

由于您明确指定b的变量类型为Unit,因此lambda实际上不会return 42。另一方面,如果让编译器推断出函数类型或者适当地指定它,那么最后一个lambda语句将成为结果,在这种情况下类型为Int

以下两种情况都是可能的:

val b1: () -> Unit = { 42 }
val b2: () -> Int = { 42 }

以及这些(直接调用lambda):

val a1: Unit = { 42 }() 
val a2: Int = { 42 }() 

可以找到文档here

  

lambda表达式总是被花括号括起来,完整语法形式的参数声明进入花括号内部并具有可选的类型注释,正文遍历 - &gt;标志。 如果lambda的推断返回类型不是Unit,则lambda主体内的最后一个(或可能是单个)表达式将被视为返回值。