美文网首页
【2019-05-20】内建控制结构

【2019-05-20】内建控制结构

作者: BigBigFlower | 来源:发表于2019-05-20 13:03 被阅读0次

    scala内建的控制结构:if、while、for、try、match和函数调用,scala从语法层面支持函数字面量。
    (1)if 表达式

    // if检测条件并根据是否为真,执行两个分支中的一个
    var filename = "default.txt"
      if (!args.isEmpty)
        filename = args(0)
    
    
    //优化,根据条件做初始化
    val filename =
        if (!args.isEmpty) args(0)
        else "default.txt"
    

    val 和var:val不能再次赋值,var可以在它生命周期中被多次赋值。
    (2)while循环

    object Misc {
      var loopcounter = 2
    
      def ifVariations(args: Array[String]) {
        println("args [" + args.toList + "]")
    
        {
          var filename = "default.txt"
          if (!args.isEmpty)
            filename = args(0)
          println("filename [" + filename + "]")
        }
    
        {
          val filename =
            if (!args.isEmpty) args(0)
            else "default.txt"
          println("filename [" + filename + "]")
        }
    
        println(if (!args.isEmpty) args(0) else "default.txt")
      }
    //while 循环
      def gcdLoop(x: Long, y: Long): Long = {
        var a = x
        var b = y
        while (a != 0) {
          val temp = a
          a = b % a
          b = temp
        }
        b
      }
    //使用递归计算最大公约数
      def gcd(x: Long, y: Long): Long =
        if (y == 0) x else gcd(y, x % y) 
    
      def whileLoop() {
        def readLine() = {
          if (loopcounter > 0) {
            loopcounter -= 1
            "a line"
          } else
            ""
        }
    //do-while 循环
        var line = ""
        do {
          line = readLine()
          println("Read: "+ line)
        } while (line != "")
      }
    
      def shadowing() {
        val a = 1;
        {
          val a = 2 // Compiles just fine
          println(a)
        }
        println(a)
      }
    
      def shadowing2() {
        val a = 1;
        {
          val a = 2;
          {
            println(a)
          }
        }
      }
    }
    
    Misc.ifVariations(Array("foo"))
    Misc.ifVariations(Array())
    println("gcdLoop(2, 4) [" + Misc.gcdLoop(2, 4) + "]")
    println("gcdLoop(3, 4) [" + Misc.gcdLoop(3, 4) + "]")
    println("gcd(2, 4) [" + Misc.gcd(2, 4) + "]")
    println("gcd(3, 4) [" + Misc.gcd(3, 4) + "]")
    Misc.whileLoop()
    Misc.shadowing()
    Misc.shadowing2()
    

    (3)for表达式

    object Files {
     val filesHere = (new java.io.File(".")).listFiles
    //枚举集合类
    //列举文件中的列
     def printFiles() {
       for (file <- filesHere)
         println(file)
     }
    
     def printFilesIter() {
       // Not common in Scala...
       for (i <- 0 to filesHere.length - 1)
         println(filesHere(i))
     }
    //用带过滤器的for发现.scala文件
     def printScalaFiles() {
       val filesHere = (new java.io.File(".")).listFiles
       
       for (file <- filesHere if file.getName.endsWith(".scala"))
         println(file)
     }
    
     def printScalaFiles2() {
       for (file <- filesHere)
         if (file.getName.endsWith(".scala"))
           println(file)
     }
    
    //在for表达式中使用多个过滤器
     def printScalaFiles3() {
       for (
         file <- filesHere
         if file.isFile;//如果有多个过滤器,if子句必须使用分号分隔
         if file.getName.endsWith(".scala")
       ) println(file)
     }
    //嵌套循环
     def fileLines(file: java.io.File) = 
       scala.io.Source.fromFile(file).getLines.toList
    
     def grepParens(pattern: String) {
    
       def grep(pattern: String) =
         for (
           file <- filesHere
           if file.getName.endsWith(".scala");
           line <- fileLines(file)
           if line.trim.matches(pattern) 
         ) println(file +": "+ line.trim)
       
       grep(pattern)
     }
    
     def grepGcd() {
       def grep(pattern: String) = grepParens(pattern)
       grep(".*gcd.*")
     }
    
     def grepGcd2() {
    //流间(mid-stream)变量绑定,绑定的变量(trimmed)作为val引入和使用,不过不带关键字val,trimmed变量从半路引入for表达式,初始化为line.trim的结果值。
       def grep(pattern: String) =
         for {
           file <- filesHere
           if file.getName.endsWith(".scala")
           line <- fileLines(file)
           trimmed = line.trim
           if trimmed.matches(pattern)  
         } println(file +": "+ trimmed)
       
       grep(".*gcd.*")
     }
    //制造新集合,创建一个值去记住每一次的迭代
    //for{子句}yield{循环体},yield在整体循环之前。
     def scalaFiles =
       for {
         file <- filesHere
         if file.getName.endsWith(".scala")
       } yield file
    
     val forLineLengths =
       for {
         file <- filesHere
         if file.getName.endsWith(".scala")
         line <- fileLines(file)
         trimmed = line.trim
         if trimmed.matches(".*for.*")  
       } yield trimmed.length
    }
    
    Files.printFiles()
    Files.printFilesIter()
    Files.printScalaFiles()
    Files.printScalaFiles2()
    Files.printScalaFiles3()
    Files.grepParens(".*asdf.*")
    Files.grepGcd()
    Files.grepGcd2()
    println("Files.scalaFiles.toList [" + Files.scalaFiles.toList + "]")
    println("Files.forLineLengths.toList [" + Files.forLineLengths.toList + "]")
    

    (3)使用try表达式处理异常

    object Exceptions {
      def throws1 {
        throw new IllegalArgumentException
      }
    //抛出异常,创建一个异常对象然后用throw关键字抛出
    //throw的结果类型的表达式。如果n是偶数,返回n/2,否则异常抛出
      def throws2(n: Int) = {
        val half =
          if (n % 2 == 0)
            n / 2
          else
            throw new RuntimeException("n must be even")
        half
      }
    
      def throws3 {
        import java.io.FileReader
        import java.io.FileNotFoundException
        import java.io.IOException
        //try-catch捕获异常
        try {
          val f = new FileReader("input.txt")
          // Use and close file
          println("f [" + f + "]")
        } catch {
          case ex: FileNotFoundException => // 处理丢失的文件
            println("ex [" + ex + "]")
          case ex: IOException => // 处理其他I/o错误
            println("ex [" + ex + "]")
        }
      }
    //try-finally
      def finally1 {
        import java.io.FileReader
        
        val file = new FileReader("input.txt")
        try {
          // Use the file
        } finally {
          file.close()  // Be sure to close the file
        }
      }
    
      import java.net.URL
      import java.net.MalformedURLException
      
      def urlFor(path: String) =
        try {
          new URL(path)
        } catch {
          case e: MalformedURLException =>
            new URL("http://www.scala-lang.org")
        }
      def f(): Int = try { return 1 } finally { return 2 }
      def g(): Int = try { 1 } finally { 2 }
    }
    
    try {
      Exceptions.throws1
    } catch {
      case ex =>
        println("ex [" + ex + "]")
    }
    
    try {
      println("Exceptions.throws2(2) [" + Exceptions.throws2(2) + "]")
      Exceptions.throws2(3)
    } catch {
      case ex =>
        println("ex [" + ex + "]")
    }
    
    Exceptions.throws3
    println("Exceptions.urlFor(\"blah\") [" + Exceptions.urlFor("blah") + "]")
    println("Exceptions.f [" + Exceptions.f + "]")
    println("Exceptions.g [" + Exceptions.g + "]")
    

    (5)match匹配表达式

    object Match {
     def match1(args: Array[String]) {
       val firstArg = if (args.length > 0) args(0) else ""
       
       firstArg match {
         case "salt" => println("pepper")
         case "chips" => println("salsa")
         case "eggs" => println("bacon")
         case _ => println("huh?")
       }           
     }
    
     def match2(args: Array[String]) {
       val firstArg = if (!args.isEmpty) args(0) else ""
       
       val friend =
         firstArg match {
           case "salt" => "pepper"
           case "chips" => "salsa"
           case "eggs" => "bacon"
           case _ => "huh?"
         }           
       
       println(friend)
     }
    
    }
    
    Match.match1(Array())
    Match.match1(Array("foo"))
    Match.match1(Array("eggs"))
    
    Match.match2(Array("chips"))
    

    (6)变量范围

    def printMultiTable() {
    
      var i = 1
      // only i in scope here
    
      while (i <= 10) {
    
        var j = 1
        // both i and j in scope here
    
        while (j <= 10) {
    
          val prod = (i * j).toString
          // i, j, and prod in scope here
    
          var k = prod.length
          // i, j, prod, and k in scope here
    
          while (k < 4) {
            print(" ")
            k += 1
          }
    
          print(prod)
          j += 1
        }
    
        // i and j still in scope; prod and k out of scope
    
        println()
        i += 1
      }
    
      // i still in scope; j, prod, and k out of scope
    }
    
    printMultiTable()
    

    (7)重构指令式风格的代码

    // 以序列形式返回一行乘法表
    def makeRowSeq(row: Int) =
      for (col <- 1 to 10) yield {
        val prod = (row * col).toString
        val padding = " " * (4 - prod.length)
        padding + prod
      }
    
    // 以字符串形式返回一行乘法表
    def makeRow(row: Int) = makeRowSeq(row).mkString
    
    // 以字符串形式返回乘法表,每行占一行字符串
    def multiTable() = {
    
      val tableSeq = // 行记录字符串的序列
        for (row <- 1 to 10)
        yield makeRow(row)
    
      tableSeq.mkString("\n")
    }
    
    println("multiTable [" + multiTable + "]")
    

    相关文章

      网友评论

          本文标题:【2019-05-20】内建控制结构

          本文链接:https://www.haomeiwen.com/subject/hnvhzqtx.html