icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Kotlin语言基础

    • 数据类型
    • 数组的使用
    • Kotlin集合
    • Kotlin流程控制
      • 1. for循环
        • for元素遍历
        • for下标遍历
        • for遍历元素(带索引)
        • forEach遍历数组
        • forEach增强版
        • for循环使用小结
      • 2. While循环被保留
      • 3. 实例测试
      • 4. goto语句,标签处返回
        • 标签处返回
      • 5. Range范围表达式
        • .. 运算符
        • downTo表达运算符
        • 范围表达式也可表示连续的字符串
        • 可以使用关键字 in 判断范围匹配
        • 范围表达式也可以写作对象的方法
      • 6. When表达式
        • 不写break的case
        • 结合范围表达式
        • 范围表达式取非
        • when表达式嵌套语句示例
      • 7. 三目运算符
    • Kotlin方法
    • 类和方法
    • Lambda表达式
    • Kotlin泛型
  • Kotlin笔记
  • Kotlin语言基础
iqqcode
2021-06-02
目录

Kotlin流程控制

【参考文档】

  • 🎈Kotlin 循环控制 (opens new window)

# 1. for循环

# for元素遍历

for (item in array) { // 元素遍历
    print(item )
    // 1 2 3 4 5
}
1
2
3
4

Java for-each循环

for (item : list)
1

Kotlin也能使用类似形式的循环,区别在于把冒号 : 换成了关键字 in,具体语句形如 for (item in list)

下面是Kotlin对数组进行循环处理的代码例子:

fun main(args: Array<String>) {
    val poemArray: Array<String> = arrayOf("朝辞白帝彩云间", "千里江陵一日还", "两岸猿声啼不住", "轻舟已过万重山")

    for (item in poemArray) {
        print("$item,\n")
    }

    println("========================\n")
    
    for (i in poemArray.indices) {
        if (i % 2 == 0)  println("${poemArray[i]},") 
        else println("${poemArray[i]}。")
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# for下标遍历

Kotlin in 关键字也可以替代for-i循环

for (i in poemArray.indices) { }

for (i in array.indices) {  // 根据下标再取出对应位置的元素
    println(i.toString() + "->" + array[i])=
    // 0->1
    // 1->2,
    // 2->3,
    // 3->4,
    // 4->5
}
1
2
3
4
5
6
7
8
9
10

然而取消 for (初始; 条件; 增减) 这个规则是有代价的,因为实际开发中往往存在非同一般的需求,比如以下几种情况,Kotlin的 for (i in array.indices) 语句就无法很好地处理:

  1. 如何设定条件判断的起始值和终止值?
  2. 每次循环之后的递增值不是1的时候要怎么办?
  3. 循环方向不是递增而是递减,又如何是好?
  4. 与条件判断有关的变量不止一个,咋整?
  5. 循环过程中的变量,在循环结束后还能不能使用?

针对以上情况,其实Kotlin也给出了几个解决办法,代价是多了诸如 until、step、downTo 这样的关键字,具体用法见下列代码:

// 左闭右开区间 [11, 66),合法值包括11,但不包括66
for (i in 11 until 66) { ... }

// 每次默认递增1,这里改为每次递增4
for (i in 23..89 step 4) { ... }

// for循环默认递增,这里使用downTo表示递减
for (i in 50 downTo 7) { ... }
1
2
3
4
5
6
7
8

可是这些解决办法并不完美,因为业务需求是千变万化的,并非限定在几种固定模式。同时,以上规则容易使人混淆,一旦没搞清until和downTo的开闭区间,在判断边界值时会产生问题。所以更灵活的解决方案是:起止数值、条件判断、循环方向与递增值都应当在代码中明确指定,for (初始; 条件; 增减) 这个规则固然废除了,但开发者依旧能够使用while语句实现相关功能

# for遍历元素(带索引)

for ((index, item) in array.withIndex()) {  // 同时遍历下标 和 元素
    println("$index->$item")
    // 0->1
    // 1->2
    // 2->3
    // 3->4
    // 4->5
}
1
2
3
4
5
6
7
8

# forEach遍历数组

array.forEach {
    println(it)
    // 1
    // 2
    // 3
    // 4
    // 5
}
1
2
3
4
5
6
7
8

# forEach增强版

array.forEachIndexed { index, item ->
    println("$index:$item")
    // 0:1
    // 1:2
    // 2:3
    // 3:4
    // 4:5
}
1
2
3
4
5
6
7
8

# for循环使用小结

for (i in 1..4) print(i)  // 打印结果为: "1234"
1

如果你需要按反序遍历整数可以使用标准库中的 downTo() 函数:

(也可以先array.reverse()翻转)

for (i in 4 downTo 1) print(i)  // 打印结果为: "4321"
1

也支持指定步长:

for (i in 1..4 step 2) print(i) // 打印结果为: "13"

for (i in 4 downTo 1 step 2) print(i) // 打印结果为: "42"
1
2
3

如果循环中不要最后一个范围区间的值可以使用 until 函数:

for (i in 1 until 10) { // i in [1, 10), 不包含 10
     println(i)
}
1
2
3

# 2. While循环被保留

while循环

val poemArray: Array<String> = arrayOf("朝辞白帝彩云间", "千里江陵一日还", "两岸猿声啼不住", "轻舟已过万重山")
    val poem: String = ""
    var i: Int = 0
    while (i < poemArray.size) {
        if (i % 2 == 0) {
            println("${poemArray[i]},")
        } else {
            println("${poemArray[i]}。")
        }
        i++
    }
    println("${poem}该诗歌一共有${i}句。")
1
2
3
4
5
6
7
8
9
10
11
12

do...while循环:同Java


# 3. 实例测试

前面的循环处理其实都还中规中矩,只有内忧没有外患,但要是数组里的诗句本身就不完善,比如有空指针、有空串、有空格串、有多余串等等,此时就得进行诗句的合法性判断,如此方可输出正常的诗歌文字。合法性判断主要由两块代码组成:

  1. 如果发现有空指针、有空串、有空格串,则忽略此行,即使用关键字continue继续下个循环;
  2. 如果合法诗句达到四句,则不管是否遍历完成,直接拼好绝句并结束循环,即使用关键字break跳出循环;加入了合法性判断的代码见下,主要演示了continue 和 break:
fun main(args: Array<String>) {
    val poemArray: Array<String?> = 
    arrayOf("朝辞白帝彩云间", null, "千里江陵一日还", "", "两岸猿声啼不住", "   ", "轻舟已过万重山", "送孟浩然之广陵")
    
    var pos: Int = -1
    var count: Int = 0
    while (pos <= poemArray.size) {
        pos++
        if (poemArray[pos].isNullOrBlank())
            continue
        if (count % 2 == 0) {
            println("${poemArray[pos]},")
        } else {
            println("${poemArray[pos]}。")
        }
        count++
        if (count == 4)
            break
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 4. goto语句,标签处返回

外层循环加个@标记

fun main(args: Array<String>) {
    val poemArray: Array<String?> = 
    arrayOf("朝辞白帝彩云间", null, "千里江陵一日还", "", "两岸猿声啼不住", "   ", "轻舟已过万重山", "送孟浩然之广陵")
    
    var i: Int = 0
    var is_found = false
    outside@ while (i < poemArray.size) {
        var j: Int = 0
        val item = poemArray[i];
        if (item != null) {
            while (j < item.length) {
                if (item[j] == '一') {
                    is_found = true
                    break@outside
                }
                j++
            }
        }
        i++
    }
    println(if (is_found) "我找到'一'字啦" else "没有找到'一'字呀")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 标签处返回

Kotlin 有函数字面量、局部函数和对象表达式。因此 Kotlin 的函数可以被嵌套。 标签限制的 return 允许我们从外层函数返回。 最重要的一个用途就是从 lambda 表达式中返回。回想一下我们这么写的时候:

fun foo() {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}
1
2
3
4
5
6

这个 return 表达式从最直接包围它的函数即 foo 中返回。 (注意,这种非局部的返回只支持传给内联函数的 lambda 表达式。) 如果我们需要从 lambda 表达式中返回,我们必须给它加标签并用以限制 return。

fun foo() {
    ints.forEach lit@ {
        if (it == 0) return@lit
        print(it)
    }
}
1
2
3
4
5
6

现在,它只会从 lambda 表达式中返回。通常情况下使用隐式标签更方便。 该标签与接受该 lambda 的函数同名。

fun foo() {
    ints.forEach {
        if (it == 0) return@forEach
        print(it)
    }
}
1
2
3
4
5
6

或者,我们用一个匿名函数替代 lambda 表达式。 匿名函数内部的 return 语句将从该匿名函数自身返回

fun foo() {
    ints.forEach(fun(value: Int) {
        if (value == 0) return
        print(value)
    })
}
1
2
3
4
5
6

当要返一个回值的时候,解析器优先选用标签限制的 return,即

return@a 1
1

意为"从标签 @a 返回 1",而不是"返回一个标签标注的表达式 (@a 1)"。




# 5. Range范围表达式

# .. 运算符

双点运算符,简化了对范围的表达

fun main(args: Array<String>) {
    
    // 这个范围表示了从 1 到 10 
    val res = 1..10
}
1
2
3
4
5

# downTo表达运算符

downTo正好是与双点运算符是相反的

// 这个范围表示了从 10 到 1
val res = 10 downTo 1
1
2

步长为2的downTo 表达运算符

 // 这个范围表示了从 10 到 1,但是步长为 2:即 10、8、6、4、2
val res = 10 downTo 1 step 2 
1
2

# 范围表达式也可表示连续的字符串

 // 这个范围表示了从 a 到 z : "a","b","c","d"...."z"
 val res = "a".."z"
1
2

# 可以使用关键字 in 判断范围匹配

 // 这个范围表示了从 a 到 z : "a","b","c","d"...."z"
 val res = "a".."z"
 val contains = "a" in res
1
2
3

# 范围表达式也可以写作对象的方法

    // 这个范围表示了从 1 到 10
    val r5 = 1.rangeTo(10)

    // 这个范围表示了从 10 到 1
    val r6 = 10.downTo(1)
1
2
3
4
5

# 6. When表达式

kotlin的when其实就是对java的switch的一个升级

switch分支语句

String ans = "B";
switch (ans) {
    case "A":
        // TODO
        break;
    case "B":
        // TODO
        break; 
    default:
        break;
}
1
2
3
4
5
6
7
8
9
10
11

when分支语句

String ans = "A";
when (ans) {
    "A" -> {
        // TODO
    }
    "B" -> {
        // TODO
    }
    else -> {
        // TODO
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

当我们的需要的分支枚举完毕,可以使用 else 指向默认分支

fun main(args: Array<String>) {
    val x = 7
    val numbersList = arrayListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    when (x) {
        in 1..5 -> println("x is in range of 1 to 10")
        in numbersList -> print("x in numbersList range")
        else -> print("X is not in the range and its value of x is $x")
    }
}
1
2
3
4
5
6
7
8
9

# 不写break的case

fun main(args: Array<String>) {
    val x = 1
    val numbersList = arrayListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    when (x) {
        in 1..10 -> println("x is in range of 1 to 10") 
        in numbersList -> print("x in numbersList range") // 此处不会执行
        else -> print("X is not in the range and its value of x is $x")
    }
}

>>> output: x is in range of 1 to 10
1
2
3
4
5
6
7
8
9
10
11

不写break的话会接着执行下一个case进行比较么?

  • 不是的,这个when的结果是只会执行当前分支的内容,后跳出当前when

如何像java一样不写break的话会执行多个呢?

var num = 6;
when (num) {
    in 1..20 -> {
        // TODO
    }
}

var res = "null"
when (res) {
    is String -> {
        // TODO
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  • is 就是 Java的 instanceof
  • as 就是用来强制类型转换的

# 结合范围表达式

# 范围表达式取非

fun main(args: Array<String>) {
    val x = 15
    when (x) {
        !in 10..20 -> print("x is outside the range")
        else -> print("none of the above")
    }
}

>>> output: none of the above
1
2
3
4
5
6
7
8
9

# when表达式嵌套语句示例

fun main(args: Array<String>) {
    val x = 10
    val y = 7
    val z = 20
    val result = when (z) {
        20 -> {
            println("if z id 20 then doing the sum of x and y")
            x + y
        }
        30 -> {
            println("if z id 30 then subtracting y from x")
            x - y
        }
        else -> "none of the value matched"
    }
    println("The result is $result")
}

>>> output: if z id 20 then doing the sum of x and y
The result is 17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 7. 三目运算符

fun maxOf(a: Int, b: Int) = if (a > b) a else b
1

Tips:如果你使用if作为表达式而不是语句(例如:返回它的值或者把它赋给变量),该表达式需要有 else分支。


【原文转载】:

[1] aqi00. Kotlin入门(7)循环语句的操作[EB/OL]. https://www.cnblogs.com/aqi00/p/7192967.html

[2] 苗小帅. Kotlin之流程控制[EB/OL]. https://www.jianshu.com/p/01eaac5f8767

编辑 (opens new window)
#kotlin
上次更新: 2022/06/04, 11:36:35
Kotlin集合
Kotlin方法

← Kotlin集合 Kotlin方法→

最近更新
01
匿名内部类
10-08
02
函数式接口
10-08
03
ARouter-Kotlin踩坑
10-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×