本文主要内容翻译自Kotlin references。
在Java中,if
关键字只能用来表示一个语句块,语句块是没有值的,也就是说我们不能将一个if语句块赋值给某个变量。Kotlin为if
关键字赋予了其他的作用,使其能够代替condition? exp1 : exp2
三元运算符,正因“if-else表达式”替代了三元运算,所以Kotlin中不包含三元运算符。
Kotlin中if
和 if-else
语句块的使用方法和Java 没有区别,不再赘述。
作为表达式的时候,else
是必须的(这很好理解)。if-else 表达式使用方法和Java中的三元运算没有什么区别:
val max = if(a > b) a else b
强烈建议!只将 if-else表达式应用于上述的简单场景。
Kotlin没有,
运算符(不是作为分隔符使用), 但是它提供了其它的解决方案,在Java中可以使用如下的语句在选择最大值的同时执行打印:
//Java
int max = a > b ? println("a is larger"), a : println("b is larger"), b;
由于没有,
运算符,同样的功能在Kotlin中可以使用如下代码实现:
val max = if(a > b) {
print("a is larger")
a
}else {
print("b is larger")
b
}
类似于,
运算符,最后一个表达式的值是整个表达式的值。
等价于 switch-case 并且自带break以及if-else-if语句块的合体。语法稍有区别,最大的不同在于switch-case语句块以及if-else-if语句块是没有值的,但when可以当做有值的表达式赋值给变量。
等价于 switch-case 并且自带break。语法稍有不同,如下:
when(x) {
1 -> print("one")
2 -> print("two")
3, 4 -> print("three or four")
else -> {
print("not 1, 2, 3 or 4")
}
}
从前往后匹配,直到条件满足则执行相应语句并退出when语句块,每一个匹配项中可以包含多个备选值,如果没有找到特定匹配则匹配else,else在when语句块中是可选的。
每一个分支不一定都用常量表示,可以是具值表达式,也可以使用 in
或 !in
检查数值是否在范围内,甚至使用is
或!is
判断类型:
when (x) {
!is Int -> print("x isn't Int")
parseInt(s) -> print("s encodes x")
in 1..10 -> print("x is in range")
else -> print("none of the above")
}
如果我们使用is
判断出变量的类型,那么就可以在对应的字句中使用该类的方法。
when语句还可以等价于 if-else-if 语句块,使用方法如下:
when {
someone.isBoy -> print("is a boy")
someone.isGirl -> print("is a girl")
else -> print(" 0.0 ?? ? ")
}
和Kotlin中的 if-else 表达式相同,when也可以作为表达式使用,在when表达式中,else分支是必须的。具体使用同 if-else 表达式类似,不再赘述。
Kotlin对for循环的功能做了减法,在Kotlin中for循环只能用于迭代访问可迭代对象,格式如下:
for(item: type in collection) {
//do something
}
元素类型是可选的。
如前所述,Kotlin中的for只能应用与可迭代对象访问。可迭代对象应该满足以下要求:
iteration()
方法(成员方法或者扩展方法)返回迭代器,返回的迭代器应满足如下条件: next()
方法(成员方法或者扩展方法)hasNext()
方法(成员方法或者扩展方法)特别地,当for循环应用与数组时,编译器会将其转化为基于下标的访问,而不会用迭代器。
如果需要访问下标值,那么可以使用数组的indices()
方法返回下标数组:
for(i in array.indices) {
print(array[i])
}
或者直接获取下标和对应的元素值:
for((index, value) in array.withIndex()) {
print("the element at $index is $value")
}
for循环还能用于访问某个范围的所有值。注意,这种访问会被编译器优化而不会创建额外的迭代器对象:
for(i in 1..10 step 2) {
print(i)
}
step
是可选的,用于指定递增值且该值必须为正,如果没有则默认递增值为1。
while 和 do-while 语句和 Java 相同。
break 和 continue可以像之前一样使用,即break用于跳出当前循环、continue用于跳过当前循环并继续下一轮循环。
在这个基础上,Kotlin还支持额外的标签跳转。例如:
OUTLOOP@ for(i in 1..10){
for(j in 1..10) {
if(...) break@OUTLOOP
}
}
定义标签使用标签名+@的方法(没有空格),使用标签则是break@+标签名的方式(没有空格)。以上代码当break语句被执行时将会直接跳出外层循环。
在没有标签break和标签continue的Java中,要实现类似的功能会比较麻烦。通常我们需要在外层循环中定义一个flag,在内层循环中的条件满足时修改该flag然后使用break语句退出内层循环,内层循环退出时检验该flag是否被修改进而决定是否退出外层循环。Kotlin的标签break和标签continue语法有效的消除了这些模板代码。