MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Kotlin控制流与条件语句详解

2023-02-236.7k 阅读

Kotlin控制流与条件语句详解

if 语句

在Kotlin中,if语句是最基本的条件判断结构,用于根据给定的条件来决定是否执行特定的代码块。它的基本语法形式与许多其他编程语言类似,但在Kotlin中,if语句不仅可以作为语句使用,还可以作为表达式使用,这意味着它可以返回一个值。

  1. 基本语法(语句形式)
val num = 10
if (num > 5) {
    println("数字大于5")
}

在上述代码中,if关键字后面跟着一个条件num > 5,如果这个条件为真,就会执行大括号内的代码块,即打印"数字大于5"

  1. else分支的if语句
val num = 3
if (num > 5) {
    println("数字大于5")
} else {
    println("数字小于等于5")
}

这里,如果num > 5条件为假,就会执行else关键字后面大括号内的代码块。

  1. 多层嵌套的if - else语句
val num = 10
if (num > 10) {
    println("数字大于10")
} else if (num == 10) {
    println("数字等于10")
} else {
    println("数字小于10")
}

在这个例子中,我们通过else if实现了多层条件判断。首先检查num > 10,如果为假,接着检查num == 10,如果还是为假,就执行最后的else分支。

  1. if作为表达式 在Kotlin中,if语句可以作为表达式使用,这意味着它可以返回一个值,这在很多场景下非常方便。例如:
val num = 10
val result = if (num > 5) "大于5" else "小于等于5"
println(result)

在上述代码中,if (num > 5) "大于5" else "小于等于5"整体就是一个表达式,它会根据条件返回相应的字符串,然后赋值给result变量。

when 语句

when语句在Kotlin中是一种更强大的条件分支结构,类似于其他语言中的switch - case语句,但功能更丰富。

  1. 基本语法
val num = 2
when (num) {
    1 -> println("数字是1")
    2 -> println("数字是2")
    3 -> println("数字是3")
    else -> println("其他数字")
}

when后面跟着一个表达式num,然后通过->符号连接条件和相应的执行代码块。当num的值与某个条件匹配时,就会执行对应的代码块。如果没有匹配的条件,就会执行else分支(else分支可选)。

  1. 匹配多个值
val day = 6
when (day) {
    6, 7 -> println("周末")
    in 1..5 -> println("工作日")
    else -> println("无效的日期")
}

在这个例子中,6, 7表示day的值为6或者7时执行相应代码块,in 1..5表示day的值在1到5之间时执行相应代码块。

  1. 基于类型的匹配 when语句还可以根据对象的类型进行匹配,这在处理不同类型对象的业务逻辑时非常有用。
fun printType(obj: Any) {
    when (obj) {
        is Int -> println("这是一个整数")
        is String -> println("这是一个字符串")
        else -> println("未知类型")
    }
}
val num = 10
printType(num)
val str = "Hello"
printType(str)

这里通过is关键字来判断对象的类型。如果objInt类型,就执行is Int对应的代码块;如果是String类型,就执行is String对应的代码块。

  1. when作为表达式if语句一样,when语句也可以作为表达式使用,返回一个值。
val num = 5
val result = when (num) {
    in 1..10 -> "在1到10之间"
    else -> "不在1到10之间"
}
println(result)

在这个例子中,when表达式根据num的值返回不同的字符串,并赋值给result变量。

for 循环

for循环在Kotlin中用于迭代遍历一个区间、集合或其他可迭代对象。

  1. 遍历区间
for (i in 1..5) {
    println(i)
}

这里1..5表示一个从1到5的闭区间,for循环会依次将区间内的每个值赋给i,然后执行循环体,即打印i的值。

  1. 遍历区间并指定步长
for (i in 1..10 step 2) {
    println(i)
}

step 2表示步长为2,所以循环会打印1、3、5、7、9。

  1. 反向遍历区间
for (i in 5 downTo 1) {
    println(i)
}

downTo关键字用于反向遍历区间,这里会从5依次递减到1并打印。

  1. 遍历集合
val list = listOf("apple", "banana", "cherry")
for (fruit in list) {
    println(fruit)
}

Kotlin中的集合类(如ListSetMap等)都是可迭代的,for循环可以直接遍历集合中的每个元素。对于Map,可以使用for ((key, value) in map)的形式来同时获取键和值。

while 循环

while循环用于在满足特定条件时重复执行一段代码块。

  1. 基本while循环
var num = 0
while (num < 5) {
    println(num)
    num++
}

在这个例子中,只要num < 5条件为真,就会一直执行循环体。循环体中先打印num的值,然后num自增1。

  1. do - while 循环 do - while循环与while循环类似,但它会先执行一次循环体,然后再检查条件。
var num = 5
do {
    println(num)
    num++
} while (num < 5)

在这个例子中,即使初始时num < 5条件为假,循环体也会先执行一次,打印5,然后由于num自增后num < 5为假,循环结束。

控制流语句中的跳转

在Kotlin的控制流语句中,有几个关键字用于实现跳转操作,如breakcontinuereturn

  1. break关键字 break用于终止循环。在嵌套循环中,它默认终止最内层循环,但也可以通过标签来终止外层循环。
outerLoop@ for (i in 1..5) {
    for (j in 1..5) {
        if (i * j == 10) {
            break@outerLoop
        }
        println("$i * $j = ${i * j}")
    }
}

在上述代码中,当i * j == 10时,break@outerLoop会终止名为outerLoop的外层循环。

  1. continue关键字 continue用于跳过当前循环的剩余部分,直接进入下一次循环。
for (i in 1..10) {
    if (i % 2 == 0) {
        continue
    }
    println(i)
}

这里如果i是偶数(i % 2 == 0),就会执行continue,跳过println(i),直接进入下一次循环,所以只会打印奇数。

  1. return关键字 return用于从函数中返回,在控制流语句中,如果在局部函数或Lambda表达式中使用return,它的行为会有所不同。
fun findFirstEvenNumber(list: List<Int>): Int? {
    list.forEach { number ->
        if (number % 2 == 0) {
            return number
        }
    }
    return null
}
val numbers = listOf(1, 3, 5, 4, 7)
val result = findFirstEvenNumber(numbers)
println(result)

在这个findFirstEvenNumber函数中,当找到第一个偶数时,通过return返回该偶数。如果遍历完列表都没有找到偶数,则返回null

总结控制流与条件语句的应用场景

  1. if语句的应用场景
    • 简单条件判断:当只需要根据一个简单的布尔条件决定是否执行某段代码时,if语句是首选。例如,在登录验证中,判断用户名和密码是否正确:
val username = "admin"
val password = "123456"
if (username == "admin" && password == "123456") {
    println("登录成功")
} else {
    println("用户名或密码错误")
}
  • 赋值操作中的条件判断:由于if可以作为表达式,在根据条件进行赋值时非常方便。比如根据用户的权限级别设置不同的操作权限:
val userRole = "admin"
val canDelete = if (userRole == "admin") true else false
  1. when语句的应用场景
    • 多条件分支判断:当有多个离散的条件需要判断时,when语句比多层嵌套的if - else语句更简洁易读。例如,根据用户输入的命令执行不同的操作:
val command = "print"
when (command) {
    "print" -> println("执行打印操作")
    "save" -> println("执行保存操作")
    "exit" -> println("执行退出操作")
    else -> println("未知命令")
}
  • 类型匹配:在处理不同类型对象的业务逻辑时,when的类型匹配功能十分强大。比如在一个图形绘制库中,根据不同的图形类型进行绘制:
abstract class Shape
class Circle : Shape()
class Rectangle : Shape()
fun draw(shape: Shape) {
    when (shape) {
        is Circle -> println("绘制圆形")
        is Rectangle -> println("绘制矩形")
    }
}
val circle = Circle()
val rectangle = Rectangle()
draw(circle)
draw(rectangle)
  1. for循环的应用场景
    • 遍历区间:常用于需要按照一定范围进行迭代的场景,如生成序列号、循环执行固定次数的任务等。例如,生成1到100的序列号:
for (i in 1..100) {
    println("序列号:$i")
}
  • 遍历集合:在处理集合数据时,for循环是最常用的遍历方式。比如统计列表中某个元素的出现次数:
val list = listOf("apple", "banana", "apple", "cherry")
var count = 0
for (fruit in list) {
    if (fruit == "apple") {
        count++
    }
}
println("苹果出现的次数:$count")
  1. while循环的应用场景
    • 条件不确定的循环:当不知道具体需要循环多少次,而依赖于某个条件来决定是否继续循环时,while循环比较合适。例如,在读取文件内容时,直到文件末尾才停止读取:
import java.io.File
val file = File("example.txt")
val reader = file.bufferedReader()
var line: String?
while (reader.readLine().also { line = it } != null) {
    println(line)
}
reader.close()
  • 需要先执行一次的循环do - while循环适用于需要先执行一次操作,然后再根据条件决定是否继续的场景。比如用户登录,至少需要让用户输入一次用户名和密码,然后根据验证结果决定是否继续让用户输入:
var username: String
var password: String
do {
    println("请输入用户名:")
    username = readLine() ?: ""
    println("请输入密码:")
    password = readLine() ?: ""
    if (username == "admin" && password == "123456") {
        println("登录成功")
    } else {
        println("用户名或密码错误,请重新输入")
    }
} while (username != "admin" || password != "123456")
  1. 控制流跳转关键字的应用场景
    • break关键字:在循环中,当满足某个特定条件需要立即终止循环时使用。比如在一个搜索算法中,当找到目标元素时停止搜索:
val list = listOf(1, 3, 5, 7, 9, 10)
var found = false
for (num in list) {
    if (num == 10) {
        found = true
        break
    }
}
if (found) {
    println("找到目标元素")
} else {
    println("未找到目标元素")
}
  • continue关键字:当需要跳过循环中某些不符合条件的迭代,继续执行下一次迭代时使用。比如在计算列表中所有奇数的和时,跳过偶数:
val list = listOf(1, 2, 3, 4, 5)
var sum = 0
for (num in list) {
    if (num % 2 == 0) {
        continue
    }
    sum += num
}
println("奇数的和:$sum")
  • return关键字:在函数中,当完成特定任务需要返回结果或者提前结束函数执行时使用。比如在一个查找最大值的函数中,找到最大值后返回:
fun findMax(list: List<Int>): Int {
    var max = Int.MIN_VALUE
    for (num in list) {
        if (num > max) {
            max = num
        }
    }
    return max
}
val numbers = listOf(1, 3, 5, 2, 4)
val maxNumber = findMax(numbers)
println("最大值:$maxNumber")

通过深入理解和灵活运用这些控制流与条件语句,开发者能够编写出逻辑清晰、高效的Kotlin程序,满足各种复杂的业务需求。无论是简单的条件判断,还是复杂的循环迭代和跳转控制,这些语句都是构建Kotlin应用程序的重要基石。