这3个语法在js里也有,但在kotlin里,用法似乎完全不太一样
在说这3个语法之前,先说下标签
用途是 控制代码的执行流程,想跳哪里 就跳哪里
c语言里也有标签(使用的是 标签名:
定义标签,然后用 goto 标签名
来跳转到标签处)
在kotlin里 使用 标签名@
定义一个标签, 使用 return、break、continue 跳转到标签处
// 定义一个名为loop的标签
loop@ for (i in 1..100) {
// ……
}
// 在多个循环外层定义一个标签,然后在内层循环中根据条件,跳到外层循环的标签处
outerLoop@ for (i in 1..3) {
for (j in 1..3) {
if (i == 2 && j == 2) {
break@outerLoop
}
println("i: $i, j: $j")
}
}
//输出:
//i: 1, j: 1
//i: 1, j: 2
//i: 1, j: 3
//i: 2, j: 1
这个用法其他编程语言也有
fun sum(a: Int, b: Int): Int {
return a + b //返回a+b的值
}
这个用法其他编程语言也有
fun sum(a: Int, b: Int): Int {
if (a > b) return a //如果a>b,就提前退出函数,返回a的值
println(a)
}
感觉有些类似其他语言里的continue,用于跳过本次循环
下方的 lit@
表示定义了一个标签, 似乎c语言里也有这种类似的东西,是用goto来跳转的?记不太清了
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // 返回 lit标签的位置,实现了跳出本次循环的功能
print(it)
}
print("done")
// 输出 1245done ,跳过了 等于3的情况
}
上面的代码还可以简写
lambda 函数有个隐式标签,就是它的函数名,上面的代码可以简写成下面这样
fun foo() {
listOf(1, 2, 3, 4, 5).forEach{
if (it == 3) return@forEach // 返回 隐式标签forEach的位置,实现了跳出本次循环的功能
print(it)
}
print("done")
// 输出 1245done ,跳过了 等于3的情况
}
也可以这样用,可以在满足条件的情况下,替换值
val numbers = listOf(1, 2, 3, 4, 5)
val result = numbers.map {
if (it == 3) {
return@map -1 // 跳过本次循环,并返回-1
}
it * 2 // 返回it * 2
}
println(result) // 输出:[2, 4, -1, 8, 10] ,原来的3被替换成了-1
再来一个用法
fun main() {
run loop@{
println("loop开始执行")
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // 直接跳转到loop@处, 这时候程序 就会 去执行 println("main执行完毕") 这一行了
print(it)
}
println("loop执行完毕")
}
println("main执行完毕")
}
//输出:
//loop开始执行
//1
//2
//main执行完毕
可以跳出本层循环
如果是嵌套多层的循环,可以 配合标签 来实现
要跳出本层循环,直接break就行
for (i in 1..3) {
for (j in 1..3) {
if (j == 2) {
break // 如果j==2 那本层循环就结束, 尽管后面还可能有 j等于3 等于4的情况,通通抛弃
}
println("i = $i, j = $j; ")
}
}
// 输出
// i = 1, j = 1;
// i = 2, j = 1;
// i = 3, j = 1;
如果是嵌套多层的循环,想要跳出 ,就可以用 break配合标签 来实现
fun main() {
outerLoop@ for (i in 1..3) {
for (j in 1..3) {
if (j == 2) {
break@outerLoop // 跳出到outerLoop标签处, 从内到外的循环都终止,包括名为outerLoop标签的循环
}
println("i = $i, j = $j; ")
}
}
// 输出
// i = 1, j = 1;
}
continue 用于跳过当前循环的剩余部分,直接进入下一次循环
也可以搭配标签,跳过多层循环的剩余部分
for (i in 1..3) {
for (j in 1..3) {
if (j == 2) {
continue //当j=2就跳过当前循环后续的代码,即不执行后面的println语句,而是继续执行本层循环的下一次迭代(即j不等于2的情况)
}
println("i = $i, j = $j; ")
}
}
// 输出(你会发现输出里,没有j==2的情况,因为都被跳过了):
// i = 1, j = 1;
// i = 1, j = 3;
// i = 2, j = 1;
// i = 2, j = 3;
// i = 3, j = 1;
// i = 3, j = 3;
fun main() {
outerLoop@ for (i in 1..3) {
for (j in 1..3) {
if (j == 2) {
continue@outerLoop //当j=2就跳到outerLoop标签 标记的那层循环
}
println("i = $i, j = $j; ")
}
}
// 输出、推演:
// i = 1, j = 1; // 没进入if,所以println执行了
// 推演: 在这里本来应该输出i = 1, j = 2;,但进入了if,于是丢弃本层循环,跳到outerLoop标签标记的那层循环,并继续执行
// i = 2, j = 1; // 到了这里,i等于2,j等于1 ,没进入if,所以println执行了
// 推演: 在这里本来应该输出i = 2, j = 2;,但进入了if,于是丢弃本层循环,跳到outerLoop标签标记的那层循环,并继续执行
// i = 3, j = 1; // 到了这,i等于3,j等于1 ,没进入if,所以println执行了
// 推演: 在这里本来应该输出i = 3, j = 2;,但进入了if,于是丢弃本层循环,跳到outerLoop标签标记的那层循环,并继续执行
// 推演: 到这里 外层的循环已经执行完了,所以结束了
}
我认为如果把两者 比喻为一个人的话
那么 break
是那种,做事决绝,不留后路 的人 (结束本层循环)
而 continue
是 属于做人留一线,做事不那么决绝 的人 (只结束 本层循环的某次迭代 )
for (i in 1..3) {
for (j in 1..3) {
if (j == 2) {
break // 如果j==2 那本层循环就结束, 尽管后面还可能有 j等于3 等于4的情况,通通抛弃
}
println("i = $i, j = $j; ")
}
}
// 输出
// i = 1, j = 1;
// i = 2, j = 1;
// i = 3, j = 1;
for (i in 1..3) {
for (j in 1..3) {
if (j == 2) {
continue //当j==2就跳过本层循环的本次迭代的后续代码,即不执行后面的println语句,而是继续执行本层循环的下一次迭代(即j等于3、4、5、6 ... 的情况)
}
println("i = $i, j = $j; ")
}
}
// 输出(你会发现输出里,没有j==2的情况,因为都被跳过了):
// i = 1, j = 1;
// i = 1, j = 3;
// i = 2, j = 1;
// i = 2, j = 3;
// i = 3, j = 1;
// i = 3, j = 3;
只想结束本层循环的某个迭代,就用 continue,它可以让你继续
想结束本层循环, 就用 break ,它可以让你 休息、停止
通过他们的英文含义,就容易理解了