返回块中的最后一个表达式
我正在学习新的,非常漂亮的Kotlin语言,一切似乎都是非常符合逻辑的。 我只发现了一件似乎是规则的任意例外的东西,而不是一个坚实的规则。 但也许我缺乏足够的理解背后的一些深层原因。
我知道,在if-else
和when
语句中有代码块,则返回最后一个表达式。 在下面的例子中,根据条件返回1
或2
– 在我们的例子中返回1
。
val x = if (1 < 2) {println("something"); 1} else {println("something else"); 2}
另一方面,这不适用于任何代码块。 下一行将y
分配给1
但将整个代码块分配给一个lambda。
val y = {println("something"); 1}
同样在函数体中,最后一个表达式不被返回。 这甚至没有编译。
fun z() : Int { println("something") 1 }
那么规则究竟是什么? 它是否真的如此随心所欲:如果在if-else
或when
用作表达式的语句中有一段代码,则返回该块中的最后一个表达式。 否则,最后一个表达式不会返回到外部作用域。 还是我错过了什么?
你误解了大括号{}
,当所有的flow-control
语句只是一个块 ,例如:
if (condition) { //block here }
当 {}
分开声明时,它是一个lambda表达式,例如:
val lambda: () -> Int = { 1 }; // lambda
当你想在if-else
表达式中返回一个lambda
表达式时,你必须加大括号{}
或者使用圆括号()
来区分块和lambda表达式,或者明确地使用lambda表达式,例如:
val lambda1: () -> Int = if (condition) { { 1 } } else { { 2 } }; val lambda2: () -> Int = if (condition) ({ 1 }) else ({ 2 }); val lambda3: () -> Int = if (condition) { -> 1 } else { -> 2 };
如果一个函数没有返回任何有用的值,它的返回类型是
Unit
。Unit
是只有一个值的Unit
。 这个值不必显式返回。
另一方面,如果一个公共 function
的返回类型不是一个Unit
:
fun z(): Int { return 1; }
另一种情况是函数返回Nothing
, return
语句根本不允许,因为你不能创建一个Nothing
实例,例如:
fun nothing(): Nothing { return ?;// a compile error raising }
当一个函数只有一个表达式时,可以使用单表达式函数 ,例如:
fun z() = 1;
lambda块和“普通”块之间是有区别的,在你的情况下,“y”只是一个需要执行的lambda来获取返回的值:
val block: () -> Int = { 5 } val five: Int = { 5 }() val anotherFive = block()
所以如果你想要一个用作lambda的块,你可以创建一个lambda并用“()”立即执行。 这样,你的“z”函数就会这样编译:
fun z() : Int = { println("something") 1 }()
(这当然没有多大意义,效率也不高)