kotlin学习笔记-return、break、continue

这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

return

return的用法-返回一个值

这个用法其他编程语言也有

fun sum(a: Int, b: Int): Int {
   return a + b //返回a+b的值
}

return的用法-提前退出

这个用法其他编程语言也有

fun sum(a: Int, b: Int): Int {
   if (a > b) return a //如果a>b,就提前退出函数,返回a的值
   println(a)
}

return的用法-返回到标签处

感觉有些类似其他语言里的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的情况
}
 

return的用法-返回到标签处,返回一个值

也可以这样用,可以在满足条件的情况下,替换值

   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

return的用法-返回到标签处

再来一个用法

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

break的用法-跳出循环

可以跳出本层循环

如果是嵌套多层的循环,可以 配合标签 来实现

break 跳出本层循环

要跳出本层循环,直接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 跳出多层循环

如果是嵌套多层的循环,想要跳出 ,就可以用 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

continue的用法-跳过本次循环

continue 用于跳过当前循环的剩余部分,直接进入下一次循环

也可以搭配标签,跳过多层循环的剩余部分

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;

continue 跳过多层循环,不执行后续的代码

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 的区别

我认为如果把两者 比喻为一个人的话

那么 break 是那种,做事决绝,不留后路 的人 (结束本层循环)

continue 是 属于做人留一线,做事不那么决绝 的人 (只结束 本层循环的某次迭代 )

从下面2个例子,看看他们的细微差别

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;

break 和 continue 的总结

只想结束本层循环的某个迭代,就用 continue,它可以让你继续

想结束本层循环, 就用 break ,它可以让你 休息、停止

通过他们的英文含义,就容易理解了