Scala_Scala _ Scala 中 逻辑控制

 

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

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值