流程控制
程序的运行可以分成顺序执行,分支执行和循环执行。顺序执行自不必多说。Scala的分支和循环与Java类同,只记录Scala特殊的部分。
一、分支执行 if-else
要注意Scala中的if-else具有返回值:
var age = StdIn.readInt()
val res = if(age < 18){
"青少年"
}else{
"承诺人"
"成年人"
}
println(res)
注:(1)默认返回的返回值是花括号内的最后一句代码,如上述代码中,如果不满足if条件,则返回“成年人”。
(2)当出现以下情况时:
var age = StdIn.readInt()
val res = if(age < 18){
"青少年"
}else{
age
}
println(res)
此时若满足if条件,则返回一个String,不满足则返回一个Int,那么res的类型是什么呢?答案是Any,这是因为String是引用类型,它的父类是AnyRef。Int的父类是AnVal,AnyRef和Anyval的共同父类就是Any。所以如果你要自己定义res的类型,应该如下所示:
val res : Any = if(age < 18){
"青少年"
}else{
age
}
二、循环执行 For
Scala的for循环与Java有较大的区别,先回顾下Java的for循环:
for(int i = 1; i <= 10 ; i++){
//循环代码
}
Scala的for循环是一种范围数据循环,简单代码如下:
for(i <- 1.to(9)){
println(i+"我是for循环")
}
其中,i表示循环变量,<-可以理解为一个箭头,把1.to(9)方法的值遍历给i;1.to(9)表示从1-9的循环,前后闭合。
需要注意的是,Scala中支持“空格”调用方法,且在只有一个参数时,不需要空格,故上述代码可以进一步简化:
for(j <- 1 to 9){
println(j)
}
如此一来,代码的可读性更加强。除了to方法外,还有until方法,i until j 表示从 i到 j-1,代码如下:
for(j <- 1 until 10){
println(t)
}
此段代码的输出结果与上一段相同,即循环输出9次。
此时又有了另一个问题,看一个java的循环:
for(int i = 1; i <= 10 ; i += 2){
System.out.println(i);
}
显然输入结果是:
1
3
5
7
9
我们可以把i += 2理解为步长,在Scala中如何实现步长>1的情况呢?答案如下:
for(g <- Range(1,10,2)){
println(g)
}
调用Range方法,有三个参数,Range(1,10,2)的意思是从1到10-1循环,步长为2,以上代码的输出结果应该是:
1
3
5
7
9
这种调用方法的for循环可读性不是很强,所以Scala有一个可读性更强的方法:
for(i <- 1 to 10 by 2){
println(i)
}
用by来表示步长。
三、for循环的额外特性
(1)循环守卫
for(i <- 1 to 3 if i != 2){
println(i)
}
(2)步长可以是负数
for(i <- 30 to 1 by -2){
println(i)
}
(3)可以用reverse实现反向的循环
for(i <- 1 to 30 reverse){
println(i)
}
(4)我们经常需要用到双重循环,例如在java中:
for(int i = 1; i <= 10 ; i++){
for (int j = 1; j <= i; j++){
}
}
在Scala中有更贱简单的写法:
for(i <- 1 to 9;j <- 1 to i){
println(i+"*"+j+" = "+i*j)
}
(5)引入变量:
for(i <- 1 to 9;j = 10 - i){
println(s"i=${i};j=${j}")
}
(6)循环返回值:
var a = for(i <- 1 to 10 by 2) yield i
print(a)