Kotlin条件、循环控制
IF条件控制
与Java类似,一个if语句可包含布尔表达式和一条或多条语句。
fun compare(a:Int,b:Int) : Int{//常规传统用法var max = aif (b>a) max = breturn max//使用elsevar mMax : Intif(a>b){mMax = a}else{mMax = b}return mMax//使用表达式return if (a>b) a else b
}
在Kotlin中,这里声明的时候可以更加省略,当一个函数(方法)中只有一行代码时,Kotlin允许我们不用编写函数体,可以直接将唯一的一行代码写在函数定义的尾部,中间用等号连接即可。我们统称这个为Kotlin的语法糖。
var num = if (a>b) a else b
这种语法糖用法非常重要,除了可以用于函数只有一行代码的情况外,还可以结合kotlin的很多其他语法来使用,在往后的编程示例中会用到其更多使用场景。
When表达式
类似与Java中的switch表达式,将它的参数和所有的分支条件顺序比较,直到某个分支满足条件。
按照kotlin的语法糖设计,when既可以被当作语句使用也可以被当作表达式使用。
其最简单的表达形式如下:
when (input) {1 -> print("input == 1")2 -> print("input == 2")else -> print("input 既不是 1 ,也不是 2")
}
在when表达式中,else等同于switch中的default。如果其他分支都不满足条件将会在else分支中进行逻辑处理。如果很多分支需要相同的逻辑处理,则可以将那几个分支条件放在一起,用逗号分割:
when (input) {1,2 -> print("input == 1 or input == 2")else -> print("input 既不是 1 ,也不是 2")
}
当然,when语句的分支判断也可以用 in 运算符来进行范围逻辑判断:
when (input) {in 1..10 -> print("input is in the range 1~10")!in 10..20 -> print("input is outside the range 10~20")else -> print("none of the range")
}
运算符 in 也可以用来判断集合内是否包含某实例:
fun main() {val items = setOf("car", "house", "motor" ,"plane", "train")when {"bicycle" in items -> println("bicycle")"plane" in items -> println("plane is fine too")}
}
这段代码运行后在控制台输出如图:
当然也可以用is关键字来判断检测是否是一个特定类型的值。(由于kotlin的智能转换,可以访问该类型的方法和属性而无需任何额外的检测)。
fun isPerfectString(num: Any): Boolean{return when(num){is String -> num.startsWith("perfect")else -> false}
}
根据kotlin的语法糖,这段函数可以简化为:
fun isPerfectString(num: Any) = when (num) {is String -> num.startsWith("perfect")else -> false
}
when也可以用来取代if-else来做逻辑判断,在不提供参数进行逻辑比较情况下,所有分支条件都是简单的布尔表达式,当其中分支条件为真时则执行该分支逻辑:
when {num.equals("1") -> print("num equals 1")num == 1 -> print("num == 1")else -> print("num is other situation")
}
For循环
for循环可以对任何提供迭代器的对象进行遍历操作,也可以是一段代码块:
for (element in array) print(element) //遍历集合对象for (element: Int in collection) {//遍历集合中的元素
}for (i in array.indices) {//遍历数组中的元素
}
在kotlin中,这种"在区间上遍历"不会创建额外对象,会编译成更加优化的实现。或者可以直接用库函数withIndex。
for ((index, value) in array.withIndex()) {println("the element at $index is $value")
}
写一个简单的示例:
fun main() {val items = listOf("car", "plane", "motor")for (item in items) {println(item)}for (index in items.indices) {println("item at $index is ${items[index]}")}
}
对应控制台输出为:
while与do...while循环
与Java类似,while是最基本的循环,相应结构为:
while( 布尔表达式 ) {//循环体内容
}
与Java类似,do...while循环相对于while而言,多了一个条件判断,如果不满足条件,就不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。可以说do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。
do {//逻辑代码
}while(布尔表达式);
代码结构基本与Java一致,这里不做赘述。
返回和跳转
Kotlin有三种结构跳转表达式:
✳️return:默认情况下从最近的函数或匿名函数返回。
✳️break:结束最直接包围它的闭合循环。
✳️continue: 继续下一次最直接包围它的闭合循环。
如下示例可表现其差异:
for (num in 1..10) {if (num==4) continue // num 为 4 时跳过当前循环,继续下一次循环println(num)if (num>5) break // num 为 6 时 跳出循环
}
对应控制台输出为:
Break和Continue标签
在Kotlin 中,任意表达式可以添加标签(label)。标签通过 @ 结尾来标识,比如:abc@,fooBar@ 都是有效的(参看语法)。使用标签表达式如下:
loop@ for (i in 1..100){// ...
}
现在,我们可以用标签来限制break或continue:
loop@ for (i in 1..100) {for (j in 1..100) {println(j)if (j==6) break@loop}
}
对应控制台输出为:
标签限制的break会跳转到刚好位于该标签指定的循环后面的执行点。而continue 继续标签指定的循环的下一次迭代,例如:
loop@ for (i in 1..5) {for (j in 1..5) {println(j)if (j==2) continue@loop}
}
对应的控制台输出为:
标签处返回
在字面函数,局部函数,以及对象表达式中,Kotlin 的函数(方法)可以被嵌套。而标签限制的 return 允许我们从外层函数返回。最重要的使用场景就是从lambda表达式中返回。
val ints = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8)
ints.forEach {if (it == 6) returnprint(it)
}
代码中的 return 指的是从 main 函数中返回,因为 main 函数是最直接包围它的函数,所以对应控制台输出为:
如果我们需要从 lambda 表达式中返回,我们必须给它加标签 @lit 并用以限制 return:
fun main() {val ints = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8)ints.forEach lit@{if (it == 6) return@litprint(it)}
}
对应控制台输出为:
通常情况下使用隐式标签更方便。 该标签与接受该 lambda 表达式的函数同名,上述代码即表示为:
val ints = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8)
ints.forEach {if (it == 6) return@forEachprint(it)
}
其控制台对应输出也一致。
如果不使用标签,还可以使用匿名函数替代 lambda 表达式,匿名函数内部的 return 语句将从该匿名函数自身返回。
val ints = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8)
ints.forEach(fun(value: Int) {if (value == 6) returnprint(value)
})
控制台运行结果也与之前一致。