1. Scala 的内建控制结构java
Scala 有几个内建的控制结构,包括:编程
Scala 的全部控制结构都返回某种值做为结果,这是函数式编程采起的策略:ide
程序是被用来计算出某个值,因此程序的各个组成部分也应该计算出某个值。函数式编程
以上的5个控制结构中,有一个被称之为循环,而不是表达式,由于它不会返回一个有意义的值。函数
while 和 do-while 的返回值的类型永远都是 Unit,即单元值,写做 ()。Scala 的赋值语句的结果也是 ()。spa
2. if 表达式blog
if 表达式的使用方法,大体与 Java 相同。排序
有一个区别于 Java 的使用方法,就是因为 if 表达式有返回值,因此在某些场景下能够用来赋值:资源
def main(args: Array[String]): Unit = { val fileName = if (args.isEmpty) args(0) else "default" }
3. while 和 do-while 循环字符串
while 和 do-while 循环的使用方法,也大体与 Java 相同。
可是这里须要注意的是,因为循环的结果永远都是 Unit,因此从函数式编程的角度,不建议使用循环,由于这么作纯粹是为了程序的反作用。
while 循环一般用来更新一个 var 的值,因此二者不少时候都是成对出现。
4. for 表达式
for 表达式主要用于迭代。
4.1 遍历集合
for 表达式最多见的场景就是遍历一个集合(包括 List,Set,Map,Array)
def main(args: Array[String]): Unit = { val list = List(1, 2, 3) for (i <- list) println(i) val map = Map(1 -> "1.1", 2 -> "2.2") for ((k, v) <- map) println(k + "," + v) }
4.2 遍历区间
for 表达式还能够用来遍历区间 Range,这是一种对于 Int 类的富包装。
def main(args: Array[String]): Unit = { for (i <- 1 to 3) print(i) // 输出123 for (i <- 1 until 3) print(i) // 输出12 }
其中 until 和 to 的区别在于:until 不包含上界,to 包含上界。
也可使用区间来遍历集合,但这种用法在 Scala 中不推荐:
def main(args: Array[String]): Unit = { val list = List(1, 2, 3) for (i <- 0 until list.length) println(list(i)) // 不推荐 }
4.3 过滤
遍历集合时,能够给 for 表达式增长 filter,具体的作法是在 for 表达式的圆括号中加一个 if 子句:
def main(args: Array[String]): Unit = { val list = List(1, 2, 3) for (i <- list if i > 1) println(i) // 输出23 }
支持同时使用多个 filter:
def main(args: Array[String]): Unit = { val list = List(1, 2, 3) for (i <- list if i > 1 if i % 2 == 0) println(i) // 输出2 }
4.4 嵌套迭代
for 表达式内部能够写多个 <- 子句,表示嵌套迭代。
这里写一个典型的嵌套迭代:冒泡排序
def main(args: Array[String]): Unit = { val array = Array(4, 2, 5, 1, 3) bubble(array) for (i <- array) print(i) } def bubble(array: Array[Int]) = { for (i <- 0 until array.length - 1; // 注意,嵌套迭代之间的分号是不能省略的 j <- 0 until array.length - i - 1 if array(j) > array(j + 1)) swap(array, j, j + 1) } def swap(array: Array[Int], i: Int, j: Int) = { val temp = array(i) array(i) = array(j) array(j) = temp }
须要注意的是:
所谓中途变量绑定,就是用 = 在 for 表达式内部进行临时的变量绑定(使用这个技巧能够在循环之间增长额外的操做)
def bubble(array: Array[Int]) = { for {i <- 0 until array.length - 1 // println() 编译出错 a = println() // 编译成功 j <- 0 until array.length - i - 1 if array(j) > array(j + 1)} swap(array, j, j + 1) }
4.5 yield
for 表达式在每次迭代中,均可以生成一个能够被记住的值,具体的作法实在 for 表达式的代码体以前使用 yield 关键字。
交出的值,被统一存储在一个集合里面,这个集合的类型取决于迭代子句中处理的集合种类:
def main(args: Array[String]): Unit = { val array = Array(1, 2, 3) val a = for (i <- array if i % 2 == 0) yield i // a是Array val list = List(1, 2, 3) val b = for (i <- array if i % 2 == 0) yield i // b是List }
5. try 表达式
try 表达式用来处理异常状况,与 Java 基本相同,是 try-catch-finally 结构。
try 表达式在 catch 模块与 Java 的语法不相同:
def myDivide(a: Int, b: Int): Int = { try { if (a < 0 || b < 0) throw new Exception else a / b } catch { case ex: ArithmeticException => -1 case ex: Exception => -2 // 这行注释掉编译也不会出现问题 } finally { println("Go to finally")
-3 } }
try-catch-finally 结构也会交出一个值,可是 finally 中的语句虽然始终被执行,可是却和交出值没有关系。
例如:
def main(args: Array[String]): Unit = { println(myDivide(2, -1)) // 结果是 -2 }
所以咱们能够作一个初步的总结:
6. match 表达式
Scala 的 match 表达式,从控制结构的角度上讲,对应的是 Java 的 switch-case 结构。
固然 match 表达式的做用不只限于此,它属于 Scala 的模式匹配的其中一种用法,此处不展开。
def main(args: Array[String]): Unit = { val str = if (args.length > 0) args(0) else "default" val firstArg = str match { case "1" => "one" case "default" => "zero" case _ => "nothing" // 和 Java 中的 default 关键字起相同的做用 } println(firstArg) }
Scala 的 match 表达式和 Java 的 switch-case 结构有三处区别:
7. break & continue
Scala 语言里,没有 break 和 continue 关键字。
因此若是须要相似的语义,在使用 while 或 do-while 循环,或是 for 表达式的时候,须要对程序作必定的修改。
最简单的解决方案是: