文章目录
- 背景
- 1. 分支结构
- 1.1 if 分支
- 1.1.1 if 分支作为语句使用
- 1.1.2 if 分支作为表达式使用
- 1.2 when
- 1.2.1 when 作为分支语句
- 1.2.2 when 作为表达式
- 1.2.3 when 分支处理范围
- 1.2.4 when 分支处理类型
- 1.2.5 when 条件分支— —没有条件表达式的 when 分支
- 2. 循环结构
- 2.1 while 循环
- 2.2 do while 循环
- 2.3 for-in 循环
- 2.4 控制循环结构
- 2.4.1 使用break结束循环
- 2.4.1.1 结束当前循环
- 2.4.1.2 结束当前循环同时结束外层循环
- 2.4.2 使用 continue 忽略本次循环剩下的语句
- 2.4.3 使用 return 结束方法
背景
和 Java 类似, Kotlin 也提供了两种基本的流程控制结构:分支结构和循环结构。分支结构用于根据条件来选择性的执行某段代码;循环结构用于根据循环条件重复执行某段代码。分支结构中提供了 if 和 when 两种分支语句,Kotlin 的 when 语句 可以代替 Java 的 switch 语句,而且功能更加强大; Kotlin 提供了 while, do while ,for-in 循环,抛弃了 Java 原有的普通 for 循环。
1. 分支结构
Kotlin 提供了两种常见的分支控制结构:if 分支和 when 分支。if 分支使用布尔表达式或布尔值作为分支条件来进行分支控制;而 when 分支则更适用于复杂的条件。
1.1 if 分支
1.1.1 if 分支作为语句使用
Kotlin 的 if 语句有如下三种形式:
if (expression) {
statements...//条件执行体
}
if (expression) {
statements...
} else {
statements...
}
if (expression) {
statements...
} else if (expression) {
statements...
}...//此处可以有多个 else if 语句
else{//最后一个 else 语句也可以省略
statements...
}
和 Java 类似,如果 条件执行体的大括号内就一行语句,可以省略花括号,因为单行语句本身就是一个整体。但是建议即便是一行也要使用花括号,减少出错率同时可读性更好。使用 if else 语句时有一条基本的规则:总是有限把包含范围小的条件放在前面处理。
1.1.2 if 分支作为表达式使用
Kotlin 的 if 分支还可以作为表达式使用,整个 if 表达式(包括 else 部分)返回一个值,因此 if 表达式 可以代替 Java 中的三目运算符。
例如:
fun main (args: Array<String>) {
var num = 10
//将 if 表达式的值 赋给 str 变量
var str = if (num > 5) "是大于 5 的数" else if (num < 5) "是小于 5 的数"
println(str)
}
if 表达式的分支可以是用花括号括起来的代码块,此时代码块的最后一个表达式的值将作为整个代码块的值。
1.2 when
1.2.1 when 作为分支语句
when 分支取代了 Java 中的 switch 语句,我们可以看一个例子,分别使用 Java 和 Kotlin 来实现:
public class SitchTest {
public static void main(String[] args){
char day = '1';
switch(daty){
case '1':
system.out.println("星期一");
break;
case '2':
system.out.println("星期二");
break;
case '3':
system.out.println("星期三");
break;
case '4':
system.out.println("星期四");
break;
case '5':
system.out.println("星期五");
break;
case '6':
system.out.println("星期六");
break;
default:
system.out.println("星期日");
}
}
}
将上面的 Java 的 switch 改用 Kotlin 中的 when 分支将会更加简洁, 如下:
fun main(args: Array<String>){
var day = '1'
when (day) {
'1' -> println("星期一")
'2' -> println("星期二")
'3' -> println("星期三")
'4' -> println("星期四")
'5' -> println("星期五")
'6' -> println("星期六")
else println("星期日")
}
}
when 分支与 Java 的 switch 对比,可以发现有如下变化:
- 不再使用 case 和 break 关键字;
- case 值后的冒号 改为了箭头 “->”
- default 改为了可读性更强的 else
- 如果 when 分支包含多个语句要使用花括号包裹起来
如果 when 分支只是 switch 分支的简化,那也不过如此,事实上, when 比 switch 更强大:
- when 分支可以匹配多个值;
- when 分支后的值可以不是常量,还可以是任意表达式;
- when 分支对条件表达式的类型没有任何要求
例如:
var score = 'A'
var str = "ABCDE"
when (str){
'D','E' -> {//分支匹配多个值
}
str[0] - 4, str[1] - 4 -> { // 分支值 可以是任意表达式
}
}
var date = Date()
when (date) {//when 分支的条件表达式的类型可以是任意类型,无要求
Date() -> {
}
else-> {
}
}
1.2.2 when 作为表达式
和 if 分支类似, when 分支也可以作为表达式,如果 when 分支被当做表达式,那么符合条件的分支的代码块的值就是整个表达式的值,如果分支的执行体是代码块,最后的表达式的值就是代码块的值。when 表达式也会有一个返回值,因此 when 表达式通常必须有 else 分支,除非编译器能够检测出所有的可能情况都已经被覆盖了。
例如:
fun main(args: Array<String>){
var score = 'B'
val str = when(score) {
'A' -> "优秀"
'B' -> {
println("代码块内")
"良好"
}
else -> {
println("其他")
}
}
println(str)
}
1.2.3 when 分支处理范围
我们还可以使用 in、!in 运算符,用于 when 分支检查表达式是否位于指定区间或者集合中,例如:
val age = 18
var str = when(age){
in 5..16 -> "少年"
in 17..30 -> "青年"
in 31..50 -> "青春已逝"
else -> "老幼"
}
println(str)
1.2.4 when 分支处理类型
我们可以使用is、!is 运算符,使用 when 分支检查表达是否为指定类型。例如:
var intputNum = 28
var price(inputNum: Any) = when(inputNum){
is String -> inputNum.toDouble()
is Int -> inputNum.toDouble()
is Double -> inputNum
else -> 0.0
}
1.2.5 when 条件分支— —没有条件表达式的 when 分支
当when分支不提供任何条件表达式时, when 分支可以取代 if … else if 链,每一个分支条件都是一个布尔表达式,当指定分支的布尔表达式为 true 时执行该分支,例如:
val age = 18
var str = when{// 没有条件表达式
age in 5..16 -> "少年" // 当这一条的布尔表达式的值为 true 时 就会执行这一条
age in 17..30 -> "青年" // 该行布尔表达式的值为 true ,执行结果是这一条
age in 31..50 -> "青春已逝"
!age.mathes(Regex("\\d+")) -> "错误,不是数字" //只要表达式的 布尔值是 true 就会执行
else -> "老幼"
}
println(str)
2. 循环结构
2.1 while 循环
语法格式如下:
[init_statements]
while test_expression {
body_statements
[iteration_statements]
}
2.2 do while 循环
语法格式:
[init_statements]
do
{
body_statements
[iteration_statements]
}while(test_expression)
2.3 for-in 循环
for-in 循环专用于遍历范围、序列和集合等包含的元素。语法格式如下
for(常量名 in 字符串|范围|集合){
statements
}
for-in 循环中的常量无需声明。循环中的常量会在每次循环开始时自动被赋值,因此该常量无需提前声明,只要包含在 for-in 循环的声明中,即可隐式声明该常量,无需使用 let 关键字声明;for-in 可用于遍历任何迭代对象,也就是该对象包含一个 iterator() 方法,且方法的返回值对象具有 next()、 hasNext() 方法,这三个方法都是用 operator 修饰。
例如使用 for-in 遍历计算阶乘:
fun main(args: Array<String>) {
var max = 10
var result = 1
for(num in 1..max){
result *= num
}
println(result)
}
for-in 循环的循环计数器相当于一个用 val 声明的常量,因此不允许在循环体中对循环计数器进行赋值。
2.4 控制循环结构
2.4.1 使用break结束循环
2.4.1.1 结束当前循环
循环体内使用 break 执行到这句时将结束当前循环;
2.4.1.2 结束当前循环同时结束外层循环
需要在 break 后紧跟一个标签,这个标签用于标识一个外层循环。break 后的标签必须是有效的,该标签需要在break所在循环的外层循环之前定义才有意义。如下所示:
fun main(args: Array<String>) {
//outer 作为外层循环的标识符
outer@ for (i in 0 until 10) {
//内层循环
for(j in 0 until 5) {
if(j == 4){
break@outer // 跳出当前循环的同时跳出outer 标识的外层循环
}
}
}
}
2.4.2 使用 continue 忽略本次循环剩下的语句
continue 的功能和 break 类似,只是 continue 只是忽略本次循环剩下的语句,接着开始执行下一次循环,它并不会终止整个循环。continue 和 break 类似也可以使用 @外层循环标识, 忽略本层循环剩下的语句同时忽略外层标识剩下的语句 。
2.4.3 使用 return 结束方法
return 用于结束当前所在的 方法、函数、或者匿名函数。不管循环嵌套有多少层,会直接结束所有循环。