返回块中的最后一个expression式

我正在学习新的,非常漂亮的Kotlin语言,一切似乎都是非常符合逻辑的。 我只发现了一件似乎是规则的任意例外的东西,而不是一个坚实的规则。 但也许我缺乏足够的理解背后的一些深层原因。

我知道,在if-elsewhen语句中有代码块,则返回最后一个expression式。 在下面的例子中,根据条件返回12 – 在我们的例子中返回1

 val x = if (1 < 2) {println("something"); 1} else {println("something else"); 2} 

另一方面,这不适用于任何代码块。 下一行将y分配给1但将整个代码块分配给一个lambda。

 val y = {println("something"); 1} 

同样在函数体中,最后一个expression式不被返回。 这甚至没有编译。

 fun z() : Int { println("something") 1 } 

那么规则究竟是什么? 它是否真的如此随心所欲:如果在if-elsewhen用作expression式的语句中有一段代码,则返回该块中的最后一个expression式。 否则,最后一个expression式不会返回到外部作用域。 还是我错过了什么?

你误解了大括号{} ,当所有的flow-control语句只是一个 ,例如:

 if (condition) { //block here } 

{}分开声明时,它是一个lambdaexpression式,例如:

 val lambda: () -> Int = { 1 }; // lambda 

你想在if-elseexpression式中返回一个lambdaexpression式时,你必须加大括号{}或者使用圆括号()来区分lambdaexpression式,或者明确地使用lambdaexpression式,例如:

 val lambda1: () -> Int = if (condition) { { 1 } } else { { 2 } }; val lambda2: () -> Int = if (condition) ({ 1 }) else ({ 2 }); val lambda3: () -> Int = if (condition) { -> 1 } else { -> 2 }; 

如果一个函数没有返回任何有用的值,它的返回types是UnitUnit是只有一个值的Unit 。 这个值不必显式返回。

另一方面,如果一个公共 function的返回types不是一个Unit

 fun z(): Int { return 1; } 

另一种情况是函数返回Nothingreturn语句根本不允许,因为你不能创建一个Nothing实例,例如:

 fun nothing(): Nothing { return ?;// a compile error raising } 

一个函数只有一个expression式时,可以使用单expression式函数 ,例如:

 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 }()

(这当然没有多大意义,效率也不高)