1. 程式人生 > >Scala中的控制表示式

Scala中的控制表示式

Scala中的控制表示式包含:if語法,for語法,while語法,異常語法,break語法等

我現在來梳理一下:

if表示式:我們建立一個IfExpression.scala,程式碼如下:
class IfExpression(){

  var fileName = "default.txt"
  //如果引數不為空的時候,將第一項給fileName
  def check(args: Array[String]): String=
    if(!args.isEmpty) args(0) else fileName

  println("fileName:" + fileName)
}

for語法:建立一個ForExpression.scala程式碼如下:

//for迴圈使用
class ForExpression{

  //得到檔案列表,並遍歷列印檔案
  def forFiles(): Unit = {
    val fileHere = (new java.io.File(".")).listFiles
    for(file <- fileHere)
      println("file:" + file)
  }

  def forFileIndex(): Unit = {
    val fileHere = (new java.io.File(".")).listFiles
    for(i <- 1 to fileHere.length - 1)
      println("fileHereIndex:" + fileHere(i) +" " + i)
  }

  //進行過濾filter 不同的形式
  def forFileFilter(): Unit = {
    val fileHere = (new java.io.File(".")).listFiles
    for(file <- fileHere if file.getName.endsWith(".scala"))
      println("forFileFilter:" + file)
  }

  def forFileFilter2(): Unit = {
    val fileHere = (new java.io.File(".")).listFiles
    for(file <- fileHere)
      if(file.getName.endsWith(".scala"))
        println("forFileFilter2:" + file)
  }

  def forFileFilter3(): Unit = {
    val fileHere = (new java.io.File(".")).listFiles
    for(
      file <- fileHere
      if file.isFile
      if file.getName.endsWith(".scala")
    )println("forFileFilter3:" + file)
  }

  //查詢檔案中的內容
  def fileLines(file: java.io.File) =
    scala.io.Source.fromFile(file,"UTF-8").getLines().toList

  //管道  過濾相關的字串
  def grep(pattern: String) = {
    //遍歷當前目錄下面所有的檔案
    val filesHere = (new java.io.File(".")).listFiles
    //遍歷所有的檔案
    for(file <- filesHere){
      //比較檔名是否已.scala結尾
      if(file.getName.endsWith(".scala")){
        //讀取相關檔案為檔案內容
        for(line <- fileLines(file)){
          //將檔案的內容去除空格並查詢內容裡面有pattern的檔案
          if(line.trim.matches(pattern)){
            println(file + ": " + line.trim)
          }
        }
      }
    }
  }

  //定義多個變數(stream變數)
  def grep2(pattern: String) = {
     val filesHere = (new java.io.File(".")).listFiles
     for(file <- filesHere){
       if(file.getName.endsWith(".scala")){
         for(line <- fileLines(file)){
           //定義一個變數儲存檔案的內容
           val trimmed = line.trim
           if(trimmed.matches(pattern)){
             println(file + ": " + trimmed)
           }
         }
       }
     }
  }

  //上面的迴圈中,都是執行了迴圈之後,就會清除所有元素,但是有時候我們需要將去記住,供其他使用 我們需要使用yield關鍵字

}

while語法:使用while迴圈,建立一個WhileExpression.scala,程式碼如下:

//進行while語法歸類
//while和do-while結構稱為迴圈,而不是表示式,因為它們不會產生有趣的值。
//結果的型別是Unit。事實證明,存在一個型別為Unit的值(實際上只有一個值)。
//它被稱為單位值,名為()。()的存在是Scala單元不同於Java void的地方
class WhileExpression{

  //while只要條件為真(這裡是先判斷)的情況就會執行迴圈,do-while將先執行迴圈體中的程式碼,在判斷條件
  def gcdLoop(x: Long,y: Long): Long = {
    val a = x
    val b = y
    while(a != 0){
      val temp = a
      a = b % a
      b = temp
    }
    b
  }

  def doWhileMethod(line: String){
    do{
      line = readLine()
      println("Read:" + line)
    }while(line != "")
  }

}
 

異常:建立一個ExceptionHandlerExpression.scala,程式碼如下:

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
import java.net.URL
import java.net.MalformedURLException

class ExceptionHandlerExpression{

    //丟擲異常  不許輸入為偶數
    def half(n: Int): Unit =
      if(n % 2 == 0)
        n / 2
      else
        throw new RuntimeException("n must be even")

    //使用try-catch進行異常的使用
    //與Java不同,Scala不需要捕捉檢查過的異常,或者在throw子句中宣告它們
    def tryCatchEx(): Unit = {
      try{
        val file = new FileReader("exceptionUse.txt");
        println(file)
      }catch{
        case ex: FileNotFoundException => println("不存在相應的檔案")//沒有相關檔案
        case ex: IOException => println("出現IO異常")//其他的IO異常
      } finally{
        file.close()
      }
    }

    def g(): Int =
      try{
        return 1
      }finally{
        return 2
      }

    def f(): Int =
      try{
        1
      }finally{
        2
      }

    def urlFor(path: String) =
      try{
        new URL(path)
      }catch{
        case ex: MalformedURLException =>
          new URL("https://www.baidu.com")
      }

}
並使用建立一個執行的類:ExceptionHandlerRun.scala


object ExceptionHandlerRun{

  def main(args: Array[String]){
    val exceptionHandlerExpression = new ExceptionHandlerExpression()
    exceptionHandlerExpression.half(4)   //將不丟擲異常
    exceptionHandlerExpression.half(3)  //將丟擲必須為偶數的異常
    //try-catch進行異常的使用
    exceptionHandlerExpression.tryCatchEx()
  }

}

之後我們將其他相關的放在了主的執行類中:ScalaControlStructures.scala

//scala中的控制語句
import scala.util.control.Breaks._
import java.io._

object ScalaControlStructures{
  val fileName = "default.txt"
  //scala的程式入口
  def main(args: Array[String]){
    //if語句
    val ifExpression = new IfExpression()
    println("main if expression:" + ifExpression.check(args))

    println("這是直接在方法裡面進行if語句:" + (if(!args.isEmpty) args(0) else "default.txt"))

    //for迴圈的使用
    val forExperssion = new ForExpression()
    forExperssion.forFiles()
    //to是包含4的
    for(i <- 1 to 4)
      println("forindex:" + i)

    //until 不包含4
    for(i <- 1 until 4)
      println("foruntilindex:" + i)

    //進行檔案遍歷
    forExperssion.forFileIndex()
    //進行filter過濾檔案
    forExperssion.forFileFilter()
    forExperssion.forFileFilter2()
    forExperssion.forFileFilter3()

    //grep 管道查詢相關字元
    forExperssion.grep(".*gcd.*")
    forExperssion.grep2(".*gcd.*")

    //使用match表示式
    val firstArg = if(args.length > 0) args(0) else ""

    firstArg match {
      case "tony" => println("love")
      case "love" => println("scala")
      case "name" => println("huqian")
      case _ => println("huh?")
    }

    val firstArgFriend = if(!args.isEmpty) args(0) else ""

    val friend =
      firstArgFriend match {
        case "love" => "scala"
        case "tony" => "love"
        case "name" => "huqian"
        case _ => "huhs?"
      }
    println("friend:" + friend)

    //scala中沒有continue和break關鍵字
    var i = 0
    var fountIt = false
    while(i < args.length && !fountIt){
      if(!args(i).startsWith("-")){
        if(args(i).endsWith(".scala")){
          fountIt = true
          println("i:" + i)
        }
      }
      i = i + 1
    }

    searchFrom(0,args)

    //如果在特定的場合必須要使用break的話,可以匯入scala的Breaks類,這個類在scala.util.control
    //這個類提供了一個break的方法
    // val input = new BufferedReader(new InputStreamReader(System.in))
    // breakable{
    //   while(true)
    //     println("? ")
    //     if(input.readLine() == "")
    //       break
    // }

    //變數的作用域
    printMutilTable()
    muiltTable()
  }

  def searchFrom(idx: Int,args: Array[String]): Unit =
    if(idx >= args.length) println("idx:" + -1)
    else if (args(idx).startsWith("-"))
      searchFrom(idx + 1,args)
    else if (args(idx).endsWith(".scala"))
      println("idx:" + idx)
    else
      searchFrom(idx + 1,args)

  //在同一個作用域中,只能有一個變數名相同  如果在一個作用域中使用了多個相同的變數名,將編譯失敗
  //在不同的作用域使用同樣的變數名稱,是可以通過的 取值的時候就近取值
  def printMutilTable(){
    var i = 1  //僅僅在這個作用域有用
    while(i <= 10){
      var j = 1  //i和j在這個作用域有用
      while(j <= 10){
        val prod = (i * j).toString  //i和j和prod在這個作用域有用
        var k = prod.length //i和j和prod和k在這個作用域有用
        while(k < 4){
          print(" ")
          k += 1
        }
        print(prod)
        j += 1
      }
      println()
      i += 1
    }
  }

  //返回一個序列
  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 muiltTable() = {
    val tableSeq =
      for(row <- 1 to 10)
      yield makeRow(row)

    tableSeq.mkString("\n")
  }

}

編譯執行即可