Scala学习笔记-控制结构

Scala-控制结构

Scala学习笔记-控制结构_第1张图片

控制结构是实现业务逻辑的基础,scala提供了基本的控制结构 if..else、do…while、while.. for..等,下面我们用具体的示例来对这集中结构做简要说明。

if…else…

在java、c或其他的编程语言中,if…else…是作用是控制流程分支,但scala除此之外,还提供为if..else..提供了一个更强大的功能:带返回值。实际上这也是scala语言的一大特点:几乎所有的表达式都带有返回值。

1.流程控制

根据一个boolean条件来决定程序的执行流程

      //第一个作用 逻辑控制
      val x = 10
      if(x > 10) {
          println( "x 大于10" )
      }else {
          println( "x 小于10" )
      }

2. 赋值

scala不支持三木运算符 boolean ? a : b,但这可以用if..else..轻松实现,因为scala中的if..else..带有返回值

      //第二个作用 变量初始化
      val isOpen = if( x > 10) true else false
      println(isOpen)  //false

      val result1 = if ( x > 10) x + 10 else x - 10
      println(result1)  //0

需要注意的是,当if 的返回值类型 与 else的返回值类型不同时,最终返回值类型是 两种类型的并集

 val result2: Any = if(x >  10) "bigger than 10" else x - 10
 println(result2)

上面的例子中,String和Int两种类型的并集类型为Any,所有result2是一个Any类型的引用。

另外,若只有 if 没有else 会怎么样呢?看下面的例子

 val result3 = if(x > 10) 10
 println(result3)   // () Unit

是的,result3并不是没有值,它的值是 (),即Unit,类似于java中的void,这确实有点 难以理解,但这复合scala的编码风格,你会习惯的…


while、do…while

while、do..while的用法和java或c基本相同,但有一点区别,scala中的while、do…while是有返回值的,返回值类型为Unit,即 ()

    var y = 10
    val a =  do {
         println(y)
         y -= 1
     }while(y >= 0)
     println("a:" + a)   // a:()

     var z = 10
     val b = while(z >= 0) {
         println(z)
         z -= 1
     }
     println("b:" + b)  //b:()

for

scala并没有对java格式的for进行支持,scala的for看起来更像是java中的增强for,利用他,你可以对数组,集合, 字符串等进行遍历,但这仅仅是scala中for的基本功能

  • 遍历数组
val array = Array("1","2","3","4","5")
for(a <- array){
         print(a + ",")
}
  • 遍历集合
val list = List[Int](1, 2, 3, 4, 5, 6, 7)
for(l <- list) {
     print(l + ",")
}

val set = Set("a","b","c","d")
for(s <- set) {
        print(s + " ")
}
  • 遍历字符串
    这个看起来很有意思
for(s <- "HelloWorld"){ print(s + ",") }
  • 遍历序列
    利用RichInt提供的 to 和 until方法可以产生序列
 for(i <- 0 to 10) {
        print(i + ",")  // 0 - 10
 }

 println()

 for(i <- (0 until(10, 2)) ) {
      print(i + ",") // 0,2,4,6,8,
 }
  • 遍历Map
    可以利用for来遍历map中的每一个k-v对,这得益于scala中的模式匹配,现在你不需要知道什么是模式匹配,知道怎么用就可以了。
 //遍历map
  val map_1 = Map("1"->"a", "2"->"b", "3"->"c")
  for((k, v) <- map_1) {
      print(k + "," + v + " ")
  }

  println()
  for((_, v) <- map_1) {
      print(v + " ")
  }

从上面的例子中,我们已经看出,scala中的for要比java中的for强大很多,但这还没有结束,你还可以为scala中的for雇佣一个大爷来看大门,告诉他什么人可以进,什么人不可以进,他就会严格的执行你的安排,像下面这样

 for(l <- list if l > 5) {
     print(l + ",")  // 6, 7
 }

这看起来确实很有意思,而且也很有用。
有时,你可能想利用遍历出来的每一个值产生一个中间变量,在scala中这是完全可以的

//定义
   for(i <- 1 to 10; j = 10 - i) {
       print(i + "," + j + " ")
   }

跳出循环

从上面我们看出,循环分为两类,do..while和while属于一类,for为另一类,第一类的执行依赖于一个boolean值,所以我们可以用一个boolean值来控制循环的执行

  var flag_1 = true
  var i_1 = 0
  while(flag_1) {
      i_1 += 1
      if(i_1 == 5) flag_1 = false
  }

  var flag_2 = true
  var i_2 = 0
  do{
     i_2 += 1
     if(i_2 == 6) flag_2 = false
  }while(flag_2)

对于for循环,我们可以通过break或嵌套函数的方式来跳出,对于break这种方式,scala中并没有像java中的break关键字,我们必须借助Breaks对象来完成,就像下面这样

import scala.util.control.Breaks._

  breakable {
     for(i <- 1 to 10) {
         if (i == 5) break()

         println(i)
     }
  }

这看起来很怪,但就是这样用的。需要注意的是,这种方式并不好,我们先来看一些Breaks对象的源码

关键代码如下所示:

...
def breakable(op: => Unit) {
    try {
      op
    } catch {
      case ex: BreakControl =>
        if (ex ne breakException) throw ex
    }
}

....
def break(): Nothing = { throw breakException }

我们可以看到,for被当做一个函数来执行,而break则是throw exception,也就是说break的底层是通常抛异常的形式强硬的中断了for的执行,这样的执行逻辑效率是保证不了的。

当然,我们还有办法:嵌套函数+return。这看起来更怪异

     for(i <- 1 to 10){
       print(i + "-")
       if(i > 7) return
     }
   }

  aa()

为什么要这样呢??
好了,先到这吧,欢迎补充 and 挑刺。

你可能感兴趣的:(scala)