第3章 控制结构和函数
Java 中把表达式和语句当成两个不同的东西,表达式有值,语句没有值,
只是控制结构。在 Scala 中,几乎所有语法结构都有值。
3.1 If else 表达式
scala> val x = 5 x: Int = 5 scala> val s = if( x > 0 ) 1 else -1 s: Int = 1
S 为什么会有值?
If 语句的返回类型取决于最后一条语句。语句后面的分号不是必须的。
Scala 没有三元运算符,不需要。
If 表达式会有一个返回值类型,如果 if 或者 else 返回的类型不一样,就
返回 Any 类型(所有类型的公共超类型)。
scala> val s1 = if( x > 0) "hello" else -1 s1: Any = hello scala> val s3 = if ( x < 0 ) "hello" s3: Any = ()
如果缺少一个判断,什么都没有返回,但是 Scala 认为任何表达式都会
有值,对于空值,使用 Unit 类,写做()【叫做无有用占位符,相当于 java
中的 void】
scala> val s4 = if(x < 0 ) "hello" else () s4: Any = ()
注:行尾的位置不需要分号,只要能够从上下文判断出语句的终止即可。但是如果
在单行中写多个语句,则需要分号分割。在 Scala 中,{}快包含一系列表达
式,其结果也是一个表达式。块中最后一个表达式的值就是块的值。
3.2 while 表达式
Scala 提供和 Java 一样的 while 和 do 循环,与 If 语句不同,While 语句
本身没有值,即整个 While 语句的结果是 Unit 类型的()。
while (n > 0) { r = r * n n -= 1 println(r) } do{ r = r * n n -= 1 println(r) }while(n > 0)
注:scala 并没有提供 break 和 continue 语句来退出循环,如果需要 break,可以
通过几种方法来做 1、使用 Boolean 型的控制变量 2、使用嵌套函数,从函数中
return 3、使用 Breaks 对象的 break 方法。
//循环的终止 import scala.util.control.Breaks val looper = new Breaks() //括号可以省略 var count = 0 looper.breakable{ // . 可以替换成空格 while(count <= 100){ count += 1 println(count) if(count == 10){ looper.break() } }
//多重while循环的终止 val whileLooper1 = new Breaks val whileLooper2 = new Breaks whileLooper1.breakable{ while (true){ count += 1 if(count == 10){ whileLooper1.break() } whileLooper2.breakable{ while (true){ if(count == 20){ whileLooper2.break() } } } } }
3.3 for 表达式
Scala 也为 for 循环这一常见的控制结构提供了非常多的特性,这些 for
循环的特性被称为 for 推导式(for comprehension)或 for 表达式(for
expression)。
推导式一词起源于函数式编程。
像 变量名 <- 集合 这样的表达式也被称为生成器表达式,该表达式会
基于集合生成单独的数值。
//多重for循环 for(i <- 1 to 3; j <-1 to 3){ println(i + "----" + j) println() }
//输出10 9 8 7 ... 1 for(i <- Range(10, 0, -1)){ println(i) } //输出1~9 for(i <- 1 until 10){ println(i) }
保护式,也叫守卫,可以添加一个或者多个守卫,不需要 continue 语句
//实现1~10的输出,只输出偶数 for (i <- 1 to 10 if i % 2 == 0){ println(i) }
For 推导式可以引入变量
//在for循环中添加变量表达式 for(i <- 1 to 10; j = 10 - i; m = j * i){ println("j:" + j) println("m:" + m) }
需要返回值怎么办?
使用 yield 关键字便能在 for 表达式中生成新的集合。for-yield 表达式所
生成的集合类型将根据被遍历的集合类型推导而出。
scala> val forResult = for (i <- 1 to 10) yield i forResult: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
尖叫提示:{}和()对于 for 表达式来说都可以。for 推导式有一个不成文的约定:当
for 推导式仅包含单一表达式时使用原括号,当其包含多个表达式时使用大括
号。值得注意的是,使用原括号时,早前版本的 Scala 要求表达式之间必须
使用分号。
//使用花括号作为for循环的条件包裹 for{ i <- 1 to 3 m = i * 2 } println(m) //需要使用具体的逻辑