文章目录

  • 背景
  • 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 用于结束当前所在的 方法、函数、或者匿名函数。不管循环嵌套有多少层,会直接结束所有循环。