if条件
除了和 Java 相同的 if... else if ... else
语句功能外,Scala中的if
代码块可以有返回值,即代码块最后一行会被当做返回值:
val a: Int = 10
// 可以用变量接收if的返回值
val result: Int =
if (a < 1) {
a + 1 // 代码块中的最后一句代码就是返回值
} else if (a < 10) {
a + 10
} else if (a > 100) {
a
} else {
100
}
println(result)
for循环
语法:
for( var x <- Range ){
statement(s);
}
:::info
以上语法中,Range 可以是一个数字区间表示 i to j (包含j),或者 i until j (不包含 j)。左箭头 <- 用于为变量 x 赋值。
注意:i >= j ,例如1 to 10, 不可 i < j
:::
i to j 语法(包含 j)
object Test {
def main(args: Array[String]) {
var a = 0;
// for 循环
for( a <- 1 to 10){
println( "Value of a: " + a );
}
}
}
i until j 语法(不包含 j)
object Test {
def main(args: Array[String]) {
var a = 0;
// for 循环
for( a <- 1 until 10){
println( "Value of a: " + a );
}
}
}
循环嵌套
Scala支持像 Java 一样的循环嵌套,另外,还可以将嵌套的循环写到一行中:
可以使用分号 (;) 来设置多个区间(嵌套for循环)
object Test {
def main(args: Array[String]) {
var a = 0;
var b = 0;
// for 循环
for (a <- 1 to 3; b <- 1 to 3) {
println("Value of a: " + a + "b:" + b);
}
}
}
输出结果:
Value of a: 1 b: 1
Value of a: 1 b: 2
Value of a: 1 b: 3
Value of a: 2 b: 1
Value of a: 2 b: 2
Value of a: 2 b: 3
Value of a: 3 b: 1
Value of a: 3 b: 2
Value of a: 3 b: 3
集合的嵌套循环:
val list = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) // List内部元素还是List
// 遍历
for (subList <- list; elem <- subList) {
println(elem)
}
输出结果:
1
2
3
4
5
6
7
8
9
设置步长和倒序
to
、until
方法指定步长:
:::info
步长的意思类似 i++,by 2 就是每次 + 2
:::
// 0.to(10)得到一个Range对象,然后调用Range对象的by方法指定步长
// 指定步长为2
for(i <- 0 to 10 by 2) {
println(i)
}
// 步长还可以定义为负值:当起始值大于结束值时,将步长定义为负值,则可以倒序遍历。
//(如果起始值小于结束值,步长定义为负值,那么Scala认为是死循环,就直接跳过不运行这个循环)
// 但是步长不可以设置为0
for(i <- 10 until 0 by -2) {
println(i)
}
// 也可以通过调用Range的reverse方法实现反转倒序遍历
for(i <- 0 to 10 by 2 reverse) {
println(i)
}
集合元素遍历
对于数组、集合的元素,也可以直接进行遍历:
// 遍历数组的元素
for (i <- Array(11, 24, 51, 13, 33)) {
println(i)
}
// 遍历集合的元素
for (i <- List(11, 24, 51, 13, 33)) {
println(i)
}
循环守卫
Scala的循环语句中,可以加入条件判断(即循环保护式,循环守卫),当条件判断为true
时才执行,为false
时则直接continue
(Scala中没有continue
关键字)。
例如:
// 遍历1到5中的所有偶数
for (i <- 1 to 5 if i%2 == 0) { // 直接以循环守卫的方式加入判断语句:if i%2 == 0
println(i)
}
引入变量
示例:
val list = List(10,11,12,13,14,15)
// 在循环表达式中,可以新建一个变量,即使这个变量不是嵌套循环
for (i <- 0 to 5 ; j = list(i)) {
println(j)
}
循环的返回值
通过yield
关键字声明循环要返回的内容:
// 此处的 yield 和线程无关,只是声明要返回的内容
// 返回的是一个Vector集合
val forResult = for (i <- 1 to 10) yield (i * 2) ;
println(forResult)
输出结果:
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
循环中断
Scala为了更好的适应函数式变成,去掉了 break
、continue
,推荐使用函数式的风格解决break
和continue
的功能,而不是一个关键字。
Scala中使用breakable
控制结构来实现break
和continue
功能。
对于continue
,可以使用循环守卫、if
判断等方式实现。
对于break
,可以通过抛出异常的方式实现退出。
例如:
try {
for(i <- 0 until 5) {
if (i == 3) {
throw new RuntimeException
}
println(i)
}
} catch {
case e: Exception => // 什么都不处理,只是接收异常然后退出循环
}
println("-----------------------")
使用breakable
方式退出循环(本质上也是使用抛出异常的方式):
Breaks.breakable( // 包装了的try...catch
for(i <- 0 until 5) {
if (i == 3) {
Breaks.break() // 抛出异常
}
println(i)
}
)
println("---------------")
进一步:
import scala.util.control.Breaks._ // 引入Breaks下的所有方法
// 进一步简写
breakable(
for(i <- 0 until 5) {
if (i == 3) {
break()
}
println(i)
}
)
while和do…while循环
while
和do...while
的使用和Java语言中相同。
object Test {
def main(args: Array[String]) {
// 局部变量
var a = 10;
// while 循环执行
while( a < 20 ){
println( "Value of a: " + a );
a = a + 1;
}
}
}
object Test {
def main(args: Array[String]) {
// 局部变量
var a = 10;
// do 循环
do{
println( "Value of a: " + a );
a = a + 1;
}while( a < 20 )
}
}
对于Scala这种语言,更多的是应用于Spark这类的大数据场景下的,在这种场景下,不推荐使用while
循环。因为 while
语句不像for
语句有yield
,while
没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的要使用while
外面定义的全局变量,这样就等同于循环内部的程序要操作外部的变量,对于大数据场景下不适用。而且while
可以实现的功能,for
语句都可以实现,所以推荐使用for
循环。