返回块中的最后一个表达式

V.K*_*.K. 8 kotlin

我正在学习新的和非常漂亮的语言Kotlin,一切似乎都非常合乎逻辑和一致.我只发现一件似乎是规则的任意例外而不是一条可靠的规则.但也许我对这条规则背后的一些深层原因缺乏足够的了解.

我知道在if-elsewhen语句中有代码块,然后返回最后一个表达式.在下一个例子中12根据条件返回 - 在我们的例子中它返回1.

val x = if (1 < 2) {println("something"); 1} else {println("something else"); 2}
Run Code Online (Sandbox Code Playgroud)

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

val y = {println("something"); 1}
Run Code Online (Sandbox Code Playgroud)

类似地,在函数体中,不返回最后一个表达式.这甚至都没有编译.

fun z() : Int {
    println("something")
    1
}
Run Code Online (Sandbox Code Playgroud)

那么规则到底是什么?它是否真的如此随意:如果in if-elsewhen语句用作表达式,则存在一个代码块,则返回块中的最后一个表达式.否则,最后一个表达式不会返回到外部作用域.或者我错过了什么?

hol*_*ava 8

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

if (condition) { //block here
} 
Run Code Online (Sandbox Code Playgroud)

WHEN{}单独宣称它是一个拉姆达表达,例如:

val lambda: () -> Int = { 1 }; // lambda
Run Code Online (Sandbox Code Playgroud)

您想要返回lambdain if-else表达式时,必须将大括号加倍{}或使用括号()来区分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 };
Run Code Online (Sandbox Code Playgroud)

如果函数没有返回任何有用的值,则其返回类型为Unit.Unit是只有一个值的类型 - Unit.不必显式返回此值.

另一方面,如果一个公共 的返回类型不是a,那么它function必须有一个显式return语句Unit:

fun z(): Int { return 1; }
Run Code Online (Sandbox Code Playgroud)

另一种情况是函数返回Nothing,该return语句根本不允许,因为您无法创建Nothing实例,例如:

fun nothing(): Nothing {
    return ?;// a compile error raising
}
Run Code Online (Sandbox Code Playgroud)

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

fun z() = 1;
Run Code Online (Sandbox Code Playgroud)

  • 是的,这可能就是我所说的意思。“ {}”具有三个(或什至更多?我是否缺少一些?)不同的角色-它可以是控制流语句中的块,也可以是lambda或函数体。并且所有这些情况都适用不同的规则。我并不是要抱怨或抱怨,我将不得不照原样进行。但是在我看来,这似乎是语言设计方面不一致的缺陷,而其他方面则是完美的语言。 (2认同)

obl*_*r24 5

lambda 块和“普通”块之间存在差异,在您的情况下,“y”只是需要执行才能获取返回值的 lambda:

val block: () -> Int = { 5 }
val five: Int = { 5 }()
val anotherFive = block()
Run Code Online (Sandbox Code Playgroud)

因此,如果您想要一个充当 lambda 的块,您可以创建一个 lambda 并立即使用“()”执行它。这样,你的“z”函数将像这样编译:

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

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