返回与跳转: break 与 continue
Kotlin 中存在 3 种跳出程序流程的表达式:
return
的默认行为是, 从最内层的函数或 匿名函数 中返回.break
结束最内层的循环.continue
在最内层的循环中, 跳转到下一次循环.
所有这些表达式都可以用作更大的表达式的一部分:
这些表达式的类型都是 Nothing 类型.
Break 和 Continue 的位置标签
Kotlin 中的任何表达式都可以用 label 标签来标记. 标签由标识符后面加一个 @
符号构成, 比如 abc@
, fooBar@
. 要给一个表达式标记标签, 只需要将标签放在它之前.
然后, 我们就可以使用标签来限定 break
或 continue
的跳转对象:
通过标签限定后, break
语句, 将会跳转到这个标签标记的循环语句之后. continue
语句则会跳转到循环语句的下一次循环.
使用标签控制 return 的目标
在 Kotlin 中, 通过使用字面值函数(function literal), 局部函数(local function), 以及对象表达式(object expression), 可以实现函数的嵌套. 通过标签限定的 return
语句, 可以从一个外层函数中返回. 最重要的使用场景是从 Lambda 表达式中返回. 回忆一下我们曾经写过以下代码, return
表达式会从最内层的函数 foo
中返回:
注意, 这种非局部的返回(non-local return), 仅对传递给 内联函数(inline function) 的 Lambda 表达式有效. 如果需要从 Lambda 表达式返回, 可以对它标记一个标签, 然后使用这个标签来指明 return
的目标:
这样, return
语句就只从 Lambda 表达式中返回. 通常, 使用 隐含标签 会更方便一些, 因为隐含标签的名称与 Lambda 表达式被传递去的函数名称相同.
另一种方法是, 你也可以使用 匿名函数 来替代 Lambda 表达式. 匿名函数内的 return
语句会从匿名函数内返回.
注意, 上面三个例子中局部返回的使用, 都与通常的循环中的 continue
关键字的使用很类似.
不存在与 break
直接等价的语法, 但可以模拟出来, 方法是增加一个嵌套的 Lambda 表达式, 然后在它内部使用非局部的返回:
当 return 语句指定了返回值时, 源代码解析器会将这样的语句优先识别为使用标签限定的 return 语句:
这里的含义是 "返回到标签 @a
处, 返回值为 1
", 而不是 "返回一个带标签的表达式 (@a 1)
".