Scala 中逻辑控制 跟 java 略有不同,
Scala 中逻辑控制,主要有以下几种方式:
Ⅰ for 循环
1) 基础 for 循环
2) foreach 循环
3) 带卫语句的 for 循环
4) for / yield 表达式
5) 带大括号的 for 循环
Ⅱ scala 中 break / continue 的替代方案
III scala 中 match / case
Ⅳ scala 中 try / catch / finally
Ⅵ scala 中 if else
Ⅶ scala 中 while
Ⅰ for 循环
scala 中的 for 循环 有很多种版本 与 变式,下面分别对 这些 for 循环 进行讲解。
1) 基础 for 循环 :
scala 基础的 for 循环, 与 java 的 for 循环还是有很大的区别的。
Java:
java 的 for 循环,一般按照如下的组织形式 :
for( 初始化语句 ; 循环终止条件 ; 每次循环之后进行的操作 ){
statement
}
多个条件之间 使用 , (逗号) 进行分隔
Scala :
scala 中的 for 循环,比较类似于 python 中的for 循环, 类似 for x in rang(10) 这种格式。
下面是 Scala 语言中 for 循环的语法:
for( var x <- Range ){
statement(s);
}
以上语法中,Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。
下面给出一个类似,打印 多次 , just to do it
分别使用
for (i <- 1 to 10) {
statement
}
for (i <- 1 until 10) {
statement
}
代码:
package codeControl
/**
* Created by szh on 2018/10/16.
*
* @author szh
*/
object for1Test {
def main(args: Array[String]): Unit = {
for (i <- 1 to 10) {
println(s"$i : just to do it")
}
println(" ")
println("-------------------------")
println(" ")
for (i <- 1 until 10) {
println(s"$i :just to do it ")
}
}
}
输出:
1 : just to do it
2 : just to do it
3 : just to do it
4 : just to do it
5 : just to do it
6 : just to do it
7 : just to do it
8 : just to do it
9 : just to do it
10 : just to do it
-------------------------
1 :just to do it
2 :just to do it
3 :just to do it
4 :just to do it
5 :just to do it
6 :just to do it
7 :just to do it
8 :just to do it
9 :just to do it
可见
for (i <- 1 to 10) : 是 [1, 10 ] 的双闭区间,执行10次循环
for (i <- 1 until 10) : 是 [1, 10) 的左闭右开区间,执行9次循环
2) foreach 循环
foreach 循环主要用于对 可遍历的结构进行遍历 ,示例如下:
package codeControl
/**
* Created by szh on 2018/10/29.
*/
object foreachTest1 {
def main(args: Array[String]): Unit = {
val a = Array("11", "22", 33, 44)
for((tmp,count) <-a.zipWithIndex){
println(s"$count : $tmp")
}
println(" ------------------ ")
for(tmp <- a){
println(s"$tmp ")
}
println(" ------------------ ")
val b = Map("user"->"sun",
"tel"->123456,
"addr"->"BeiJing")
for((k,v)<- b){
println(s"key: $k " + s" value: $v")
}
println(" ------------------ ")
a.foreach(println)
}
}
输出:
0 : 11
1 : 22
2 : 33
3 : 44
------------------
11
22
33
44
------------------
key: user value: sun
key: tel value: 123456
key: addr value: BeiJing
------------------
11
22
33
44
3) 带卫语句的 for 循环
scala 中的 for 可以跟随 卫语句,
简单的可以使用圆括号包裹,如以下形式:
for (i <- 1 to 10 if i < 4) {
复杂的可以使用大括号
for {
i <- 1 to 10
if i != 1
if i % 2 == 0
} {
参考代码:
package codeControl
/**
* Created by szh on 2018/10/29.
*/
object forGuardTest {
def main(args: Array[String]): Unit = {
for (i <- 1 to 10 if i < 4) {
println(i)
}
println("----------------")
//对于复杂的卫语句可以写成多行,使用 { 进行包裹
for {
i <- 1 to 10
if i != 1
if i % 2 == 0
} {
println(i)
}
println("----------------")
//for 多重循环
for {
i <- 1 to 2
j <- 1 to 3
} {
println(s"$i , $j")
}
}
}
运算结果:
1
2
3
----------------
2
4
6
8
10
----------------
1 , 1
1 , 2
1 , 3
2 , 1
2 , 2
2 , 3
4) for / yield 表达式
for / yield 可以将集合中的每个元素进行相应 处理, 从而返回一个新的集合。
for / yield 执行 类似以下过程:
1.开始运行时,for / yield 循环立即创建一个新的空集合,类型与输入的集合相同。
2.for循环每次遍历,都会在输入集合的每个元素的基础上创建新的元素,输出元素创建成功后,将其放在桶中。
3.循环结束,桶中所有的内容都被返回。
例子:
package codeControl
/**
* Created by szh on 2018/10/29.
*/
object forYieldTest {
def main(args: Array[String]): Unit = {
val k = Array("B", "a", "c")
val out = for {
tmp <- k
if tmp != "a"
}
yield {
tmp.toUpperCase
}
for (tmp <- out) {
println(tmp)
}
}
}
代码输出:
B
C
5) 带大括号的 for 循环
带大括号的for 循环主要用于较为复杂的循环,参考以上代码示例 !!
Ⅱ scala 中 break / continue 的替代方案
首先注意一点,scala 中没有 break 或者 continue 关键字,需要使用 break / continue 可以参考以下的形式。
基础的 break / continue 对比:
代码:
package codeControl
import util.control.Breaks._
/**
* Created by szh on 2018/10/29.
*/
object forBreakContinueTest {
def main(args: Array[String]): Unit = {
//continue example
for(i <- 1 to 10){
breakable{
if( i == 2 ){
break
}else{
println(i)
}
}
}
println("-----------------")
//break example
breakable{
for(i <- 1 to 10){
if(i==2){
break
}else{
println(i)
}
}
}
}
}
输出:
1
3
4
5
6
7
8
9
10
-----------------
1
多层循环:
比 Java 的 break 更加的灵活,不过更难书写
package codeControl
import scala.util.control.Breaks
//import
/**
* Created by szh on 2018/10/29.
*/
object forBreakContinueTest2 {
def main(args: Array[String]): Unit = {
val Inner = new Breaks
val Outer = new Breaks
Outer.breakable({
for (i <- 1 to 5) {
Inner.breakable({
for (j <- 'a' to 'e') {
if (i == 1 && j == 'c')
Inner.break
else
println(s"i: $i, j: $j")
if (i == 2 && j == 'b')
Outer.break
}
})
}
})
}
}
输出:
i: 1, j: a
i: 1, j: b
i: 2, j: a
i: 2, j: b
III scala 中 match / case
scala 中 不支持 swith .. case 表达式,对应的表达式 为 match... case ,
match ...case 相对于 switch ... case 更加灵活。
_ 可以捕获一切 case 的值,但是在使用通配符的情况下,不能访问该值。
default (可以写成其他的任何值)相当于给缺省匹配一个变量名,之后可在语句右侧访问该变量。
package codeControl
import scala.annotation.switch
/**
* Created by szh on 2018/10/29.
*/
object forMatchSwitchTest {
def main(args: Array[String]): Unit = {
val i = 1
val x = (i: @switch) match {
case 1 => "One"
case 2 => "Two"
case _ => "Other"
}
println(x)
println("------")
val j = 3
val y = j match {
case 1 => "One"
case 2 => "Two"
case default => default
}
println(y)
println("------")
//Example 3 : 一条case 语句匹配多个条件
val k = 5
k match {
case 1|3|5|7 => println("odd")
case 2|4|6|8 => println("even")
}
}
}
输出:
One
------
3
------
odd
注意 : 增加了 switch 注解相当于将 match 编译成了 tableswitch
Scala应用tableswitch 优化以下条件:
1.匹配的值一定是一个已知的整数
2.匹配表达式必须”简单“。既不能包含任何的类型检查,if 语句 或者抽取器 extractor
3.保证表达式在编译时的值可用
4.至少包含两个case
Ⅳ scala 中 try / catch / finally
scala 中的 try - catch 与 Java 类似,不同之处在于 catch 代码块中使用匹配表达式的方法。
catch 里面可以写多种异常 !!!
例如
package codeControl
import java.io.{FileInputStream, FileNotFoundException, FileOutputStream, IOException}
/**
* Created by szh on 2018/10/30.
*/
object TryCatchBlockTest {
def main(args: Array[String]): Unit = {
try {
val s = "dssdd"
val i = s.toInt
} catch {
case e: FileNotFoundException => println("Couldn't find that file \n " + e)
case e: IOException => println("Had an IOException trying ti read that file \n" + e)
case e: Throwable => println("another reason \n" + e)
}
println("-------------------")
//尽量不要使用 null
var in = None : Option[FileInputStream]
var out = None : Option[FileOutputStream]
try{
in = Some(new FileInputStream("/tmp/Test.class"))
out = Some(new FileOutputStream("/tmp/Test.class.copy"))
var c = 0
while({c= in.get.read; c!=1}){
out.get.write(c)
}
}catch {
case e: IOException => {
e.printStackTrace
throw e
}
}finally {
println("entered finally ...")
if(in.isDefined) in.get.close
if(out.isDefined) out.get.close()
}
}
}
输出:
another reason
java.io.FileNotFoundException: \tmp\Test.class (系统找不到指定的文件。)
java.lang.NumberFormatException: For input string: "dssdd"
at java.io.FileInputStream.open0(Native Method)
-------------------
entered finally ...
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at codeControl.TryCatchBlockTest$.main(TryCatchBlockTest.scala:30)
at codeControl.TryCatchBlockTest.main(TryCatchBlockTest.scala)
Exception in thread "main" java.io.FileNotFoundException: \tmp\Test.class (系统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at codeControl.TryCatchBlockTest$.main(TryCatchBlockTest.scala:30)
at codeControl.TryCatchBlockTest.main(TryCatchBlockTest.scala)
Ⅵ scala 中 if else
scala 不像Java, 没有特殊的三元表达式,只能使用 if / else 表达式
package codeControl
/**
* Created by szh on 2018/10/30.
*/
object forThreeTuple {
def main(args: Array[String]): Unit = {
val a = -2
val absValue = if (a < 0) -a else a
println(absValue)
}
}
输出
2
Ⅶ scala 中 while
scala 中的 while 循环跟 Java 的 while 循环非常接近,这里我们进行一个基本的演示。
package codeControl
/**
* Created by szh on 2018/10/29.
*/
object whileTest {
def main(args: Array[String]): Unit = {
var i = 0
while (i < 5) {
println(i)
i += 1
}
}
}
输出:
0
1
2
3
4