Scala模式匹配和樣例類


Scala有一個十分強大的模式匹配機制,可以應用到很多場合:如switch語句、類型檢查等。並且Scala還提供了樣例類,對模式匹配進行了優化,可以快速進行匹配。

1、字符匹配

    def main(args: Array[String]): Unit = {

      val charStr = '6'

      charStr match {

        case '+' => println("匹配上了加號")

        case '-' => println("匹配上了減號")

        case '*' => println("匹配上了乘號")

        case '/' => println("匹配上了除號")

          //注意。所有的模式匹配都必須最終匹配上一個值,如果沒有匹配上任何值,就會報錯

       // case _  => println("都沒有匹配上,我是默認值")

      }

    }

2、 匹配字符串

    def main(args: Array[String]): Unit = {

      val arr = Array("hadoop", "zookeeper", "spark")

      val name = arr(Random.nextInt(arr.length))

      name match {

        case "hadoop"    => println("大數據分布式存儲和計算框架...")

        case "zookeeper" => println("大數據分布式協調服務框架...")

        case "spark" => println("大數據分布式內存計算框架...")

        case _ => println("我不認識你...")

      }

   

}

   

3、守衛

模式匹配當中,我們也可以通過條件進行判斷

        def main(args: Array[String]): Unit = {

         var ch = "500"

         var sign = 0

         ch match {

         case "+" => sign = 1

         case "-" => sign = 2

         case _ if ch.equals("500") => sign = 3

         case _ => sign = 4

         }

         println(ch + " " + sign)

        }

   

4、 匹配類型

   

def main(args: Array[String]): Unit = {

//注意泛型擦除,在模式匹配當中的類型匹配中,除了Array類型以為,所有的其他的數據類型都會被擦除掉

val a = 3

val obj = if(a == 1) 1

else if(a == 2) "2"

else if(a == 3) BigInt(3)

else if(a == 4) Map("aa" -> 1)

else if(a == 5) Map(1 -> "aa")

else if(a == 6) Array(1, 2, 3)

else if(a == 7) Array("aa", 1)

else if(a == 8) Array("aa")

val r1 = obj match {

case x: Int => x

case s: String => s.toInt

case BigInt => -1 //不能這么匹配

case _: BigInt => Int.MaxValue

case m: Map[String, Int] => "Map[String, Int]類型的Map集合"

case m: Map[_, _] => "Map集合"

case a: Array[Int] => "It's an Array[Int]"

case a: Array[String] => "It's an Array[String]"

case a: Array[_] => "It's an array of something other than Int"

case _ => 0

}

println(r1 + ", " + r1.getClass.getName)

}

   

5、匹配數組、元組、集合

def main(args: Array[String]): Unit = {

val arr = Array(0, 3, 5)

arr match {

case Array(0, x, y) => println(x + " " + y)

case Array(0) => println("only 0")

//匹配數組以1 開始作為第一個元素

case Array(1, _*) => println("0 ...")

case _ => println("something else")

}

   

val lst = List(3, -1)

lst match {

case 0 :: Nil => println("only 0")

case x :: y :: Nil => println(s"x: $x y: $y")

case 0 :: tail => println("0 ...")

case _ => println("something else")

}

   

val tup = (1, 3, 7)

tup match {

case (1, x, y) => println(s"1, $x , $y")

case (_, z, 5) => println(z)

case _ => println("else")

}

}

   

注意:在Scala中列表要么為空(Nil表示空列表)要么是一個head元素加上一個tail列表。

9 :: List(5, 2) :: 操作符是將給定的頭和尾創建一個新的列表

注意:: 操作符是右結合的,如9 :: 5 :: 2 :: Nil相當於 9 :: (5 :: (2 :: Nil))

6、 樣例類

樣例類首先是類,除此之外它是為模式匹配而優化的類,樣例類用case關鍵字進行聲明。樣例類主要是使用在我們后面的sparkSQL當中,通過樣例類來映射我們的表當中的對象

定義形式:

case class 類型,是多例的,后面要跟構造參數。 case class Student(name:String)

case object 類型,是單例的。 case object Person

      

   

case class SubmitTask(id: String, name: String)

case class HeartBeat(time: Long)

case object CheckTimeOutTask

//1、樣例類當中的主構造器參數默認為val

//2、樣例類當中的applyunapply方法自動生成

object CaseDemo04 extends App {

val arr = Array(CheckTimeOutTask, HeartBeat(12333), SubmitTask("0001", "task-0001"))

arr(2) match {

case SubmitTask(id, name) => {

println(s"$id,$name")

println(id)

println(name)

println(id+"\t"+name)

}

case HeartBeat(time) => {

println(time)

}

case CheckTimeOutTask => {

println("check")

}

}

}

7、偏函數

被包在花括號內沒有match的一組case語句是一個偏函數,它是PartialFunction[A, B]的一個實例,A代表輸入參數類型,B代表返回結果類型,常用作輸入模式匹配,偏函數最大的特點就是它只接受和處理其參數定義域的一個子集。

                val func1: PartialFunction[String, Int] = {

                 case "one" => 1

                 case "two" => 2

                 // case _ => -1

                }

                  

                def func2(num: String) : Int = num match {

                 case "one" => 1

                 case "two" => 2

                 case _ => -1

                }

                  

                def main(args: Array[String]) {

                 println(func1("one"))

                 println(func2("one"))

                 //如果偏函數當中沒有匹配上,那么就會報錯,我們可以通過isDefinedAt來進行判斷

                 // println(func1("three"))

                 println(func1.isDefinedAt("three"))

                 if(func1.isDefinedAt("three")){

                 println("hello world")

                 }else{

                 println("world hello")

                 }

                }

   

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM