>表达式与控制语句
表达式可以被定义和赋值,如if、when关键字引导的条件语句,都是表达式
控制语句主要是for、while、do-while语句,属于循环控制语句
>条件语句(if、when)
1.if - else if - else语句
if在各种语言中的基础用法就不细提了:
if(){}
else if(){}
else{}
这里要说的是其作为表达式的形式。
先从java中的三元式说起:
int a=x>y?x:y
在Kotlin中,没有专门的三元式,而是利用了表达式的特性,进行表达:
val a:Int = if (x>y) x else y
在kotlin中约定,每个条件表达式体里的最后一行,就是返回值,如:
val a=if(x<y){
println("yes")
7
} else {
8
}
当x<y时,println(a)的正确输出应该是先打印一行"yes",再打印一行7;当x>y时,直接打印8
2.when语句
when语句是其他语言中switch语句的修改版,讲白了就是去掉了break的switch语句,如:
when(a){//假设a=9
1,2,3 -> println("Shenpibaipao")//多项选择
9 -> println(9)//满足
is Int -> println("Int")//满足
in 1 .. 8 ->println("属于[1,8]")//不满足
else -> {
println(-1)
println("执行")
}
}
->左边的是条件,右边的执行代码块(多行语句需要用{}括起来)。而
default关键字由
else进行代替。
- 其中,->左部只要是能产生布朗值的东西就行,如parseInt(a) - > xxx,当a能被转化为Int时返回true,同时执行->右边的语句。
- 还有,观察到上面的代码中,a能同时满足第二和第三个分支,但只会执行第二个分支而不会执行第三个分支,加之没有了break的设定,这就造成了它弱于switch语句的一个点:
switch(a){
case 1:
println("1");
case 2:
println("2");
case 3:
println("3");
break;
default:
break;
}
上面这个java语句用when实现起来就非常冗余(可以自行好好想想):
when(a){
1 -> {
println("1")
println("2")
println("3")
}
2 -> {
println("2")
println("3")
}
3 -> println("3")
}
也就是说,switch还可以用于一种表示“程度”的时候,when语句是完全没有switch语句简洁好用的。但从整体上来看,when语句确实是switch语句的强化版。
另外,when中的else不写的时候,默认隐含为else - >{}
同样,when语句和if语句一样,一样是一种表达式,可以像if一样进行定义和操作:
val p =when(x){
......
}
还有就是,when后面
不一定要带有选择变量,如下面这个语句一样是有效的语句:
when{
a>8 -> println("1")
}
>循环语句(for、while、do-while)
1.for语句
Kotlin中的for语句与Java中的不一样,Kotlin中的for是用作迭代的,而不是用来进行诸如for(int i=0;i<=100;i*=2)的操作的。for(item in collection)
其中,collection是任意迭代集合,可以是一个
区间或是一个
数组、图...
关于区间的应用,在上一篇说过了: http://blog.csdn.net/shenpibaipao/article/details/76805070
2.while和do-while语句
while(跳入条件){}
do{}while(跳出条件)
其最大的区别就是,do-while至少会进行一次循环体内的语句,而while则不然。
刚刚提到Java中的for(int i=0;i<=100;i*=2)已经不能用Kotlin中的for实现了,那么它只能用while来实现了:
var i:Int = 0
while(i<=100){
循环体语句
i*=2
}
看着,似乎更麻烦了==至少,我是这么觉得的。
3.跳转语句(break、continue、return以及Kotlin标签)
这三个句子的常规用法我就不说了,我们主要结合Kotlin标签来说。
Kotlin标签的定义为:
标签名@
如:Lable1@
跳转时,均为上面三个跳转语句加上标签,如:
break@Lable1
有人可能会说:“
卧槽?goto语句???”其实不然,下面来具体介绍:
先来猜猜下面这个句子的输出是什么?会不会死循环:
println("循环外1")
Label1@
//println("循环外2")//加上这句,编译报错,猜猜为什么
for(i in 1 ..5){
println(i)
if (i == 3) break@Label1
}
println("循环外3")
正确的输出是:
循环外1
1
2
3
循环外3
且,程序并不会无限循环去执行那个for。
如果把上面代码中的 break改成 continue,又会发生什么呢?其他部分保持原样,同样的代码,输出为:
循环外1
1
2
3
4
5
循环外3
依旧没有触发死循环,反而把之前没执行的println(4)和println(5)都执行了。
如果把 break改成 return呢?输出为:
循环外1
1
2
3
为什么会这样呢?
实际上,Kotlin中的标签应该叫做循环/条件语句标签,是打在一个循环/条件语句前面的,其写法意义应该更贴近:
Label1@ for(......)//注意Label1@与for同行和分行虽然都可以,但是从理解上来说,应该是分行才符合标签的用法
跳转时,只会针对某个循环进行跳转,也就是说,跳转到某个循环/条件语句上。比如对于:
Label1@ for(x1){
for(x2){
break;
}
}
此时的这个break只会跳出x2的循环,但如果是break@Label1,就会直接跳出x1的循环。
再进一步分析可得:
- break会直接跳转到标签所标示的语句之后,不再执行标签标明的语句;
- continue会跳转到标签所标示的语句,并接着执行迭代;
- return会从标签所标示的语句所在的函数中跳出,由于此处标签直接打在for上,会直接从for所在函数(也就是主函数返回,与return不带Label1@时的效果一样);但如果此时return语句在一个Lambda表达式中时。就只会从被打上标签的Lambda函数上返回,而不会直接从Main函数中返回。