7.Kotlin 流程控制:跳出循环:返回 (Return) 与跳转 (Jump)

56 阅读21分钟

希望帮你在Kotlin进阶路上少走弯路,在技术上稳步提升。当然,由于个人知识储备有限,笔记中难免存在疏漏或表述不当的地方,也非常欢迎大家提出宝贵意见,一起交流进步。 —— Android_小雨

整体目录:Kotlin 进阶不迷路:41 个核心知识点,构建完整知识体系

一、前言

1.1 跳转控制的核心作用(灵活终止 / 跳过循环、优化逻辑执行)

循环作为编程中重复执行逻辑的核心结构,在实际开发中往往需要根据动态条件调整执行节奏——比如找到目标数据后立即停止遍历以节省资源,或者过滤掉无效数据只执行有效逻辑,这些都离不开跳转控制。跳转控制的核心价值在于“打破循环的线性执行流程”,通过精准的终止、跳过操作,实现三大核心作用:

一是提升执行效率,避免无效的循环迭代(如找到目标后立即终止,无需遍历剩余数据);

二是简化逻辑实现,减少冗余的条件判断嵌套(如用跳转直接跳过无效数据,替代多层if-else);

三是控制程序流向,实现从循环到函数外层的灵活返回(如满足异常条件时直接退出函数)。

例如在遍历十万条数据查找某个关键词时,若不使用跳转控制,会强制遍历完所有数据才停止;而通过跳转控制,找到关键词后立即终止循环,能将执行效率提升成千上万倍。可见,掌握跳转控制是编写高效、简洁Kotlin代码的必备技能。

1.2 Kotlin 跳转关键字:Return、Break、Continue(核心工具)

Kotlin提供了三大核心跳转关键字,分别对应不同的跳转场景,构成了完整的跳转控制体系:

  • Break:最基础的跳转工具,作用是“立即终止当前所在的循环”,跳出循环体执行后续代码,适用于“找到目标后停止遍历”等场景;
  • Continue:用于“跳过当前循环迭代的剩余逻辑,直接进入下一次迭代”,不终止整个循环,仅过滤当前无效数据,适用于“只处理符合条件的数据”等场景;
  • Return:功能最强的跳转工具,作用是“从当前函数或匿名函数中返回”,不仅能终止循环,还能直接退出包含循环的函数,适用于“满足条件时直接结束函数逻辑”等场景。

这三个关键字既可以单独使用处理简单场景,也可以结合“标签(Label)”使用,解决嵌套循环等复杂场景的跳转问题,形成了“基础跳转+进阶标签跳转”的完整能力。

1.3 本文核心内容预告(基础用法→进阶场景→使用技巧)

本文将围绕Kotlin的跳转控制体系展开,采用“由浅入深、场景驱动”的思路逐步讲解。首先从最基础的Break和Continue入手,回顾其基本语法和简单使用场景,夯实基础;接着重点突破“标签跳转”这一进阶知识点,讲解标签的定义方式以及如何通过“标签+Break/Continue”解决嵌套循环中的精准跳转问题;然后深入分析Return跳转的两种用法(普通Return和标签Return),掌握从循环到函数的灵活返回技巧;之后通过单层循环、嵌套循环、函数返回三大实用场景,展示跳转关键字的组合应用;最后总结核心知识点、避坑技巧和选择策略,帮助读者真正做到“按需选择跳转方式,写出高效简洁代码”。

二、基础跳转:Break 与 Continue

Break和Continue是处理单层循环跳转的核心工具,也是掌握更复杂跳转场景的基础。两者都作用于当前所在的循环,但对循环的影响截然不同——Break终止循环,Continue仅跳过当前迭代。

2.1 Break:直接终止当前循环

Break的核心语义是“终止当前循环”,执行后立即跳出循环体,不再执行循环的任何后续迭代,直接执行循环之后的代码。其使用场景集中在“当满足某个条件时,循环已无继续执行的必要”,如查找目标数据、触发终止条件等。

2.1.1 基本语法(循环内直接使用)

Break的语法极为简洁,只需在循环体内部需要终止循环的位置直接写入“break”关键字即可。其在不同循环类型中的语法格式一致:

// for循环中使用break
for (元素 in 可迭代对象) {
    if (终止条件) {
        break // 满足条件,终止for循环
    }
    循环体逻辑
}

// while循环中使用break
while (循环条件) {
    if (终止条件) {
        break // 满足条件,终止while循环
    }
    循环体逻辑
}

// do/while循环中使用break
do {
    if (终止条件) {
        break // 满足条件,终止do/while循环
    }
    循环体逻辑
} while (循环条件)

语法说明:当程序执行到break时,会立即终止“当前所在的循环”(即包含break的最内层循环),无论循环的原始条件是否满足,都直接跳出循环执行后续代码。

2.1.2 简单示例(满足条件退出循环)

下面通过“遍历1到20的数字,找到第一个能被7整除的数字后终止循环”的示例,展示Break的实际使用:

fun main() {
    var target = -1 // 存储找到的目标数字
    // 遍历1到20的数字
    for (num in 1..20) {
        println("正在检查数字:$num")
        // 终止条件:数字能被7整除
        if (num % 7 == 0) {
            target = num
            break // 找到目标,终止循环
        }
    }
    println("1到20中第一个能被7整除的数字是:$target")
}

执行逻辑解析:

  • 循环从num=1开始执行,依次检查1、2、3、4、5、6,均不满足“能被7整除”的条件,执行打印逻辑后进入下一次迭代;
  • 当num=7时,7%7==0条件成立,将target设为7,执行break关键字,立即终止for循环;
  • 循环终止后,执行循环后的打印语句,不会再检查8到20的数字。

输出结果:

正在检查数字:1
正在检查数字:2
正在检查数字:3
正在检查数字:4
正在检查数字:5
正在检查数字:6
正在检查数字:7
1到20中第一个能被7整除的数字是:7

可见,Break成功实现了“找到目标后立即终止循环”的需求,避免了后续无效的迭代,提升了执行效率。

2.2 Continue:跳过当前迭代,进入下一次

Continue的核心语义是“跳过当前迭代的剩余逻辑,直接进入下一次迭代”,它不会终止整个循环,仅对当前迭代进行“过滤”。其使用场景集中在“循环体中存在部分无效数据,无需执行后续逻辑,直接处理下一个数据”,如过滤偶数、跳过空值等。

2.2.1 基本语法(循环内使用)

Continue的语法与Break类似,在循环体内部需要跳过当前迭代的位置直接写入“continue”关键字即可:

// for循环中使用continue
for (元素 in 可迭代对象) {
    if (跳过条件) {
        continue // 满足条件,跳过当前迭代,进入下一次
    }
    循环体逻辑(仅非跳过条件时执行)
}

// while循环中使用continue
while (循环条件) {
    if (跳过条件) {
        // 注意:while循环中使用continue前需更新循环变量
        循环变量更新
        continue
    }
    循环体逻辑
    循环变量更新
}

语法说明:当程序执行到continue时,会立即跳过“当前迭代中continue之后的所有逻辑”,直接进入下一次迭代的条件判断;特别注意:在while循环中使用continue时,若continue前未更新循环变量,会导致循环变量值不变,陷入无限循环。

2.2.2 简单示例(跳过不符合条件的循环体)

下面通过“遍历1到10的数字,仅打印奇数,跳过偶数”的示例,展示Continue的实际使用:

fun main() {
    println("1到10中的奇数:")
    for (num in 1..10) {
        // 跳过条件:数字为偶数
        if (num % 2 == 0) {
            continue // 跳过当前偶数的打印逻辑,进入下一次迭代
        }
        // 仅奇数会执行此打印逻辑
        println(num)
    }
}

执行逻辑解析:

  • 当num为偶数(2、4、6、8、10)时,num%2==0条件成立,执行continue,跳过后续的打印逻辑,直接进入下一次迭代;
  • 当num为奇数(1、3、5、7、9)时,不执行continue,执行打印逻辑后进入下一次迭代。

输出结果:

1到10中的奇数:
1
3
5
7
9

下面再给出while循环中使用continue的示例,注意循环变量的更新位置:

fun main() {
    println("1到10中的奇数(while循环):")
    var num = 1
    while (num <= 10) {
        if (num % 2 == 0) {
            num++ // 必须在continue前更新循环变量,避免无限循环
            continue
        }
        println(num)
        num++
    }
}

若删除continue前的“num++”,当num=2时会陷入无限循环(num始终为2,满足num%2==0和num≤10,一直执行continue)。

三、标签跳转:解决嵌套循环问题

Break和Continue单独使用时,只能作用于“包含它们的最内层循环”。而在实际开发中,嵌套循环(循环内部包含另一个循环)的场景极为常见,比如遍历二维数组、双层数据筛选等。此时若需要终止外层循环或跳过外层循环的当前迭代,单纯的Break/Continue无法满足需求,必须借助**标签(Label)**实现精准跳转。

3.1 什么是标签?(@ 符号定义循环标签)

Kotlin中的标签是一种“用于标记代码块(如循环、函数)的标识符”,通过“@”符号来定义和使用,核心作用是“为跳转关键字指定作用目标”,实现对非最内层代码块的跳转控制。

标签的定义规则极为简单:在需要标记的循环(或其他代码块)前,写入“标签名@”即可,其中标签名可自定义(遵循Kotlin标识符命名规范,如字母、数字、下划线组成,首字符为字母)。例如“outer@ for (i in 1..5)”表示为该for循环定义了一个名为“outer”的标签。

标签的使用规则:在Break或Continue后加上“@标签名”,表示“跳转到指定标签标记的代码块”,如“break@outer”表示“终止outer标签标记的循环”。

3.2 标签 + Break:终止指定循环

“标签+Break”的组合是嵌套循环中最常用的跳转方式,其核心作用是“终止标签所标记的循环(可以是外层循环)”,解决了“内层循环满足条件时需要终止外层循环”的场景。

3.2.1 语法格式(标签名 @ + 循环 + break@标签名)

// 定义外层循环标签
标签名@ for (外层元素 in 外层可迭代对象) {
    // 内层循环
    for (内层元素 in 内层可迭代对象) {
        if (终止条件) {
            break@标签名 // 终止标签名标记的外层循环
        }
        内层循环体逻辑
    }
    外层循环体逻辑(终止后不再执行)
}

语法说明:1. 先为需要控制的外层循环定义标签(如outer@);2. 在内层循环中,当满足终止条件时,使用“break@标签名”终止外层循环;3. 执行后,外层循环和内层循环都会终止,直接执行外层循环之后的代码。

3.2.2 示例(嵌套循环中退出外层循环)

需求:遍历一个二维数组(3行4列),查找是否存在数字“10”,若找到则立即终止所有循环(包括外层和内层),并打印找到的位置。此场景中,找到目标后需要终止外层循环,必须使用“标签+Break”。

fun main() {
    // 定义3行4列的二维数组
    val twoDArray = arrayOf(
        arrayOf(1, 2, 3, 4),
        arrayOf(5, 6, 10, 8),
        arrayOf(9, 11, 12, 13)
    )
    var found = false
    var rowIndex = -1
    var colIndex = -1

    // 为外层循环定义标签outer@
    outer@ for (i in twoDArray.indices) {
        for (j in twoDArray[i].indices) {
            println("正在检查第${i+1}行第${j+1}列:${twoDArray[i][j]}")
            // 终止条件:找到数字10
            if (twoDArray[i][j] == 10) {
                found = true
                rowIndex = i
                colIndex = j
                break@outer // 终止outer@标记的外层循环
            }
        }
    }

    if (found) {
        println("找到数字10,位置:第${rowIndex+1}行第${colIndex+1}列")
    } else {
        println("未找到数字10")
    }
}

执行逻辑解析:

  • 外层循环遍历行(i从0到2),内层循环遍历列(j从0到3);
  • 当i=1(第2行)、j=2(第3列)时,找到数字10,执行“break@outer”,立即终止外层循环;
  • 循环终止后,不再遍历第2行剩余列和第3行,直接执行后续的查找结果打印逻辑。

输出结果:

正在检查第1行第1列:1
正在检查第1行第2列:2
正在检查第1行第3列:3
正在检查第1行第4列:4
正在检查第2行第1列:5
正在检查第2行第2列:6
正在检查第2行第3列:10
找到数字10,位置:第2行第3列

若不使用标签,仅用普通break,会只终止内层循环,外层循环会继续遍历第3行,无法实现“找到目标后终止所有循环”的需求。

3.3 标签 + Continue:跳过指定循环的当前迭代

“标签+Continue”的组合作用是“跳过标签所标记的循环(通常是外层循环)的当前迭代,直接进入外层循环的下一次迭代”,而内层循环会正常终止当前迭代。此方式适用于“内层循环满足条件时,不需要执行外层循环当前迭代的后续逻辑,直接处理外层下一个元素”的场景。

3.3.1 语法格式(标签名 @ + 循环 + continue@标签名)

// 定义外层循环标签
标签名@ for (外层元素 in 外层可迭代对象) {
    // 内层循环
    for (内层元素 in 内层可迭代对象) {
        if (跳过条件) {
            continue@标签名 // 跳过外层循环当前迭代,进入下一次
        }
        内层循环体逻辑
    }
    外层循环体后续逻辑(跳过条件成立时不执行)
}

语法说明:1. 为外层循环定义标签;2. 在内层循环中,当满足跳过条件时,使用“continue@标签名”;3. 执行后,内层循环和外层循环的当前迭代都会终止,直接进入外层循环的下一次迭代,外层循环当前迭代的后续逻辑不再执行。

3.3.2 示例(嵌套循环中跳过外层循环当前轮次)

需求:遍历一个包含3个列表的集合,每个列表包含多个数字,要求“若某个列表中存在负数,则跳过该列表的后续处理,直接处理下一个列表”。此场景中,找到负数后需要跳过外层循环的当前迭代,需使用“标签+Continue”。

fun main() {
    // 定义包含3个列表的集合
    val listOfLists = listOf(
        listOf(1, 2, 3),    // 无负数
        listOf(4, -5, 6),   // 有负数
        listOf(7, 8, 9)     // 无负数
    )

    // 为外层循环定义标签outer@
    outer@ for (list in listOfLists) {
        println("开始处理列表:$list")
        for (num in list) {
            if (num < 0) {
                println("列表中存在负数$num,跳过该列表后续处理")
                continue@outer // 跳过外层循环当前迭代
            }
        }
        // 外层循环后续逻辑:计算列表总和(存在负数时不执行)
        val sum = list.sum()
        println("列表总和:$sum\n")
    }
}

执行逻辑解析:

  • 处理第一个列表([1,2,3])时,无负数,内层循环执行完毕后,执行外层后续逻辑,计算并打印总和;
  • 处理第二个列表([4,-5,6])时,找到负数-5,执行“continue@outer”,跳过外层循环当前迭代的后续逻辑(总和计算),直接进入下一次迭代;
  • 处理第三个列表([7,8,9])时,无负数,执行总和计算并打印。

输出结果:

开始处理列表:[1, 2, 3]
列表总和:6

开始处理列表:[4, -5, 6]
列表中存在负数-5,跳过该列表后续处理
开始处理列表:[7, 8, 9]
列表总和:24

可见,“标签+Continue”成功实现了“存在负数时跳过列表后续处理”的需求,若使用普通continue,只会跳过内层循环的当前迭代,仍会执行外层的总和计算逻辑,不符合需求。

四、Return 跳转:从循环 / 函数中返回

Return是Kotlin中功能最强大的跳转关键字,其核心作用是“从当前函数中返回”,不仅能终止循环,还能直接退出包含循环的函数。与Break(仅终止循环)相比,Return的跳转范围更大,适用于“满足条件时直接结束函数逻辑,无需执行后续代码”的场景。Return分为“普通Return”和“标签Return”两种用法,分别对应简单场景和复杂嵌套场景。

4.1 普通 Return:直接返回函数

普通Return是最常用的Return用法,在函数内部(包括循环中)直接使用“return”关键字,会立即终止当前函数的执行,返回函数的调用处,无论函数中是否有循环或其他逻辑。

4.1.1 语法(循环内使用 return)

fun 函数名(参数列表): 返回值类型 {
    // 循环
    for (元素 in 可迭代对象) {
        if (返回条件) {
            return 返回值 // 满足条件,直接返回函数
        }
        循环体逻辑
    }
    // 函数后续逻辑(返回后不再执行)
    return 默认返回值
}

语法说明:1. 在循环内部判断返回条件;2. 满足条件时,使用“return 返回值”直接退出函数;3. 执行后,循环终止,函数后续的所有逻辑(包括其他循环、普通代码)都不再执行,直接返回调用处。

4.1.2 示例(满足条件直接退出函数,终止所有循环)

需求:定义一个函数,接收一个整数列表和一个目标数字,查找目标数字是否在列表中,若找到则立即返回“找到”,若遍历完所有元素仍未找到则返回“未找到”。此场景中,找到目标后无需执行后续遍历和逻辑,适合用普通Return。

fun main() {
    val numbers = listOf(10, 20, 30, 40, 50)
    val target = 30
    val result = findNumber(numbers, target)
    println(result)
}

// 查找目标数字的函数
fun findNumber(list: List<Int>, target: Int): String {
    println("开始查找目标数字:$target")
    for (num in list) {
        println("正在检查数字:$num")
        // 返回条件:找到目标数字
        if (num == target) {
            // 直接返回函数,返回"找到"
            return "找到目标数字:$target"
        }
    }
    // 函数后续逻辑(未找到时执行)
    println("遍历完毕,未找到目标数字")
    return "未找到目标数字:$target"
}

执行逻辑解析:

  • 函数开始执行后,遍历列表中的数字10、20、30;
  • 当检查到num=30时,满足返回条件,执行“return "找到目标数字:30"”,直接退出findNumber函数,返回main函数;
  • 函数中“遍历完毕,未找到目标数字”的打印逻辑和后续代码不再执行,列表中40、50也不再检查。

输出结果:

开始查找目标数字:30
正在检查数字:10
正在检查数字:20
正在检查数字:30
找到目标数字:30

若将Return改为Break,函数会在找到目标后终止循环,但仍会执行后续的“遍历完毕”打印逻辑,返回“未找到”,不符合需求。可见Return在“立即退出函数”场景中的不可替代性。

4.2 标签 Return:返回指定标签位置

普通Return在嵌套函数(如函数内部包含匿名函数、Lambda表达式)中使用时,会默认返回“最内层的函数”,而非外层函数,这可能不符合预期。此时需要使用“标签Return”,通过标签指定返回的目标函数,实现精准返回。

标签Return的核心是“为外层函数定义标签,然后通过“return@标签名”返回该外层函数”,常见于Lambda表达式与循环结合的场景。

4.2.1 语法(return@标签名)

// 为外层函数定义标签
fun 外层函数名(参数列表): 返回值类型 {
    // 内层Lambda表达式(或匿名函数)
    集合.forEach 标签名@ { 元素 ->
        if (返回条件) {
            return@标签名 // 返回标签名标记的forEach函数(内层函数)
            // 若要返回外层函数,需用return@外层标签名
        }
        逻辑处理
    }
    return 默认返回值
}

语法说明:1. 为需要返回的函数(可以是外层函数或内层函数)定义标签;2. 使用“return@标签名”返回指定函数;3. 若标签标记的是内层函数(如forEach的Lambda),则仅终止内层函数,外层函数继续执行;若标记的是外层函数,则终止外层函数。

4.2.2 示例(嵌套场景中返回外层循环 / 函数)

需求:定义一个函数,接收一个整数列表,判断列表中是否存在“大于50且为偶数”的数字,若找到则立即返回true,否则返回false。使用forEach遍历列表(forEach的参数是Lambda表达式),此场景中需要在Lambda内部返回外层函数,需使用标签Return。

fun main() {
    val numbers = listOf(40, 55, 60, 65, 70)
    val hasTarget = hasLargeEvenNumber(numbers)
    println("列表中是否存在大于50的偶数:$hasTarget")
}

// 为外层函数定义标签hasLargeEvenNumber@
fun hasLargeEvenNumber(list: List<Int>): Boolean {
    println("开始检查列表:$list")
    // 为forEach的Lambda表达式定义标签forEach@
    list.forEach forEach@ { num ->
        println("正在检查数字:$num")
        if (num > 50 && num % 2 == 0) {
            // 返回外层函数hasLargeEvenNumber@,返回值为true
            return@hasLargeEvenNumber true
            // 若写return@forEach,则仅终止forEach,外层函数继续执行
        }
    }
    println("检查完毕,未找到目标数字")
    return false
}

执行逻辑解析:

  • 外层函数hasLargeEvenNumber定义了标签hasLargeEvenNumber@,forEach的Lambda定义了标签forEach@;
  • 当检查到num=60时,满足“大于50且为偶数”的条件,执行“return@hasLargeEvenNumber true”,直接返回外层函数;
  • forEach循环终止,外层函数的“检查完毕”打印逻辑不再执行,返回true到main函数。

输出结果:

开始检查列表:[40, 55, 60, 65, 70]
正在检查数字:40
正在检查数字:55
正在检查数字:60
列表中是否存在大于50的偶数:true

若将“return@hasLargeEvenNumber true”改为“return@forEach”,则仅终止forEach循环,外层函数会执行“检查完毕”打印逻辑并返回false,不符合需求。可见标签Return在嵌套函数场景中的精准控制作用。

五、实用场景举例

前面讲解了Break、Continue、Return的基础用法和进阶技巧,下面结合实际开发中的三大典型场景,展示这些跳转关键字的组合应用,帮助读者掌握“按需选择跳转方式”的核心能力。

5.1 单层循环跳转(Break 终止查找、Continue 过滤数据)

单层循环是最常见的循环场景,主要涉及“查找目标数据”和“过滤无效数据”两类需求,分别对应Break和Continue的使用。

场景需求:遍历一个包含姓名和年龄的用户列表,完成两个任务:1. 查找年龄为25岁的用户,找到后立即停止查找并打印;2. 过滤掉年龄小于18岁的未成年人,打印所有成年人的姓名。

// 定义用户数据类
data class User(val name: String, val age: Int)

fun main() {
    // 模拟用户列表
    val users = listOf(
        User("张三", 22),
        User("李四", 25),
        User("王五", 17),
        User("赵六", 30),
        User("钱七", 16)
    )

    // 任务1:查找年龄25岁的用户(Break终止查找)
    println("=== 任务1:查找25岁用户 ===")
    var targetUser: User? = null
    for (user in users) {
        if (user.age == 25) {
            targetUser = user
            break // 找到目标,终止循环
        }
    }
    if (targetUser != null) {
        println("找到25岁用户:$targetUser")
    } else {
        println("未找到25岁用户")
    }

    // 任务2:过滤未成年人,打印成年人姓名(Continue过滤数据)
    println("\n=== 任务2:打印成年人姓名 ===")
    for (user in users) {
        if (user.age < 18) {
            continue // 过滤未成年人,跳过打印
        }
        println("成年人:${user.name}${user.age}岁)")
    }
}

输出结果:

=== 任务1:查找25岁用户 ===
找到25岁用户:User(name=李四, age=25)

=== 任务2:打印成年人姓名 ===
成年人:张三(22岁)
成年人:李四(25岁)
成年人:赵六(30岁)

场景分析:任务1是“查找目标”,找到后无需继续遍历,用Break终止循环提升效率;任务2是“过滤数据”,仅跳过无效数据(未成年人),用Continue实现精准过滤,两者配合满足单层循环的不同需求。

5.2 嵌套循环跳转(标签控制外层循环执行)

嵌套循环在处理二维数据(如二维数组、列表的列表)时极为常见,核心需求是“精准控制外层循环的执行”,需使用“标签+Break/Continue”实现。

场景需求:遍历一个3行3列的二维数组(九宫格),完成两个任务:1. 查找是否存在数字“7”,找到后立即终止所有循环并打印位置;2. 若某一行中存在数字“0”,则跳过该行的后续处理(计算行总和),直接处理下一行。

fun main() {
    // 3行3列的二维数组(包含0和7)
    val grid = arrayOf(
        arrayOf(1, 2, 3),
        arrayOf(4, 0, 6),
        arrayOf(7, 8, 9)
    )

    // 任务1:查找数字7,找到后终止所有循环(标签+Break)
    println("=== 任务1:查找数字7 ===")
    var found = false
    var row = -1
    var col = -1
    // 定义外层循环标签outer@
    outer@ for (i in grid.indices) {
        for (j in grid[i].indices) {
            if (grid[i][j] == 7) {
                found = true
                row = i
                col = j
                break@outer // 终止外层循环
            }
        }
    }
    if (found) {
        println("找到数字7,位置:第${row+1}行第${col+1}列")
    } else {
        println("未找到数字7")
    }

    // 任务2:跳过含0的行,计算其他行总和(标签+Continue)
    println("\n=== 任务2:计算非0行总和 ===")
    // 定义外层循环标签rowLoop@
    rowLoop@ for (i in grid.indices) {
        val currentRow = grid[i]
        println("处理第${i+1}行:${currentRow.contentToString()}")
        for (num in currentRow) {
            if (num == 0) {
                println("该行包含0,跳过总和计算\n")
                continue@rowLoop // 跳过外层循环当前迭代
            }
        }
        val sum = currentRow.sum()
        println("该行总和:$sum\n")
    }
}

输出结果:

=== 任务1:查找数字7 ===
找到数字7,位置:第3行第1列

=== 任务2:计算非0行总和 ===
处理第1行:[1, 2, 3]
该行总和:6

处理第2行:[4, 0, 6]
该行包含0,跳过总和计算

处理第3行:[7, 8, 9]
该行总和:24

场景分析:任务1需要“终止所有循环”,普通Break只能终止内层循环,必须用“标签+Break”;任务2需要“跳过外层循环当前迭代”,普通Continue只能跳过内层迭代,必须用“标签+Continue”,标签跳转完美解决了嵌套循环的精准控制问题。

5.3 Return 快速退出(满足条件直接结束函数逻辑)

在函数开发中,经常需要“满足异常条件时直接退出函数,避免后续无效逻辑”,此时Return是最佳选择,能极大简化函数逻辑。

场景需求:定义一个函数,接收一个字符串列表,实现“批量校验字符串合法性”的功能,校验规则:1. 列表不能为空;2. 每个字符串长度不能小于3;3. 每个字符串不能包含数字。若满足任意一个不合法条件,立即返回错误信息;若所有字符串都合法,返回成功信息。

fun main() {
    val validList = listOf("abc", "def", "ghi")
    val invalidList1 = emptyList<String>()
    val invalidList2 = listOf("ab", "def", "ghi")
    val invalidList3 = listOf("abc", "d1f", "ghi")

    println("校验有效列表:${validateStrings(validList)}")
    println("校验空列表:${validateStrings(invalidList1)}")
    println("校验短字符串列表:${validateStrings(invalidList2)}")
    println("校验含数字字符串列表:${validateStrings(invalidList3)}")
}

fun validateStrings(strings: List<String>): String {
    // 规则1:列表不能为空
    if (strings.isEmpty()) {
        return "错误:列表不能为空"
    }

    // 规则2:字符串长度不小于3;规则3:不包含数字
    for (str in strings) {
        // 规则2校验
        if (str.length < 3) {
            return "错误:字符串\"$str\"长度小于3"
        }
        // 规则3校验
        if (str.any { it.isDigit() }) {
            return "错误:字符串\"$str\"包含数字"
        }
    }

    // 所有规则校验通过
    return "成功:所有字符串都合法"
}

输出结果:

校验有效列表:成功:所有字符串都合法
校验空列表:错误:列表不能为空
校验短字符串列表:错误:字符串"ab"长度小于3
校验含数字字符串列表:错误:字符串"d1f"包含数字

场景分析:函数中每一步校验都使用Return,满足不合法条件时立即返回错误信息,避免执行后续校验逻辑,使函数逻辑清晰、执行高效。若不使用Return,需要定义多个标志变量和多层if-else,代码会变得冗余复杂。

六、总结与使用建议

跳转控制是Kotlin流程控制的核心组成部分,掌握Break、Continue、Return的用法及标签跳转技巧,能让你编写的代码更高效、更简洁。下面总结核心知识点、避坑点和选择技巧,帮助你灵活运用跳转控制。

6.1 核心知识点回顾(Break/Continue/Return 用法 + 标签)

跳转关键字基础用法进阶用法(标签)核心作用
Break循环内直接使用,终止当前最内层循环break@标签名,终止标签标记的循环(可外层)终止循环,不退出函数
Continue循环内直接使用,跳过当前内层迭代continue@标签名,跳过标签标记的循环迭代(可外层)过滤当前迭代,不终止循环
Return函数内直接使用,退出当前函数return@标签名,退出标签标记的函数(可外层)终止循环并退出函数

标签核心:通过“标签名@”定义标签,为跳转关键字指定作用目标,解决嵌套场景的精准跳转问题。

6.2 避坑点(标签命名规范、避免过度嵌套跳转)

  • 标签命名规范:标签名需遵循Kotlin标识符命名规范,建议使用有意义的名称(如outer、rowLoop),避免使用无意义的字母(如a@、b@),提升代码可读性;
  • while循环中Continue需提前更新变量:在while循环中使用Continue时,必须在Continue前更新循环变量,否则会导致无限循环;
  • Lambda中Return默认返回内层函数:在Lambda表达式中使用普通Return时,默认返回Lambda函数而非外层函数,需使用标签Return返回外层函数;
  • 避免过度嵌套跳转:嵌套循环层数建议不超过3层,过度嵌套会导致标签跳转逻辑复杂,难以维护,可通过“提取子函数”拆分逻辑;
  • Return不可在顶层代码中使用:Return只能在函数(包括匿名函数、Lambda)内部使用,不可在顶层代码中直接使用。

6.3 选择技巧(根据场景选跳转方式,优先简洁性)

开发中选择跳转方式的核心原则是“按需选择、优先简洁”,可按照以下步骤判断:

  1. 判断是否需要退出函数:若满足条件时需要直接退出函数,选择Return;若仅需要控制循环,不退出函数,进入下一步;
  2. 判断是终止循环还是过滤迭代:若需要终止循环,选择Break;若需要过滤当前迭代,选择Continue;
  3. 判断是否为嵌套循环:若为单层循环,直接使用基础用法;若为嵌套循环,且需要控制外层循环,使用“标签+跳转关键字”;
  4. 优先简洁,避免过度设计:简单场景不使用标签,如单层循环无需标签;能通过提取子函数简化的嵌套逻辑,不依赖标签跳转。

常见场景与跳转方式对应表:

场景推荐跳转方式
单层循环查找目标数据Break
单层循环过滤无效数据Continue
嵌套循环终止外层循环标签+Break
嵌套循环跳过外层迭代标签+Continue
满足条件退出函数Return
Lambda中退出外层函数标签+Return

总之,跳转控制的核心是“精准、高效”,在满足需求的前提下,优先选择最简洁的跳转方式,避免过度使用标签和嵌套,让代码既高效又易于维护。掌握这些技巧,你就能真正驾驭Kotlin跳出循环的艺术,写出更优质的代码。