scala的模式匹配,關鍵字是match,相似於java的switch,可是功能更強大,咱們看看scala模式匹配的幾種類型。java
咱們這裏以字符串爲例。關鍵字是match,case後面經過=>
來分隔匹配的模式以及匹配後的代碼。
case是各個分支,若是匹配成功,就會執行相應的代碼塊,這裏的代碼塊能夠不用大括號。若是都不匹配,那舊執行case _裏的代碼塊,相對於java的default。數組
val str: String = "b" val result = str match { case "a" => 1 case "b" => println("b") 2 case "c" => 3 case _ => 0 } println(result) // 2
若是case b部分改如下代碼,因爲if裏的條件不符合,那他會到case _ ,返回0。app
case "b" if(str.equals("c")) => println("b")
與上面稍微有點不一樣的是,類型前面要加一個參數,這個參數能夠在後面的代碼塊裏能夠引用。函數
def main(args: Array[String]): Unit = { val array: Array[Any] = Array("a", 1, true, Array(1)) for (e <- array) { matchCase(e) } } def matchCase(v: Any): Unit = { v match { case a: Int => println(s"Int $a") case b: String => println(s"String $b") case c: Boolean => println(s"Boolean $c") case _ => println(s"Nothing") } }
運行結果以下:scala
String a Int 1 Boolean true Nothing
def main(args: Array[String]): Unit = { val array: Array[Array[Int]] = Array(Array(1), Array(0, 1), Array(1, 2), Array(1, 2, 3), Array(2, 3, 4)) for (e <- array) { matchArray(e) } } def matchArray(v: Array[Int]): Unit = { v match { // 匹配Array(1) case Array(1) => println(v(0)) // 匹配兩個長度的數組 case Array(x, y) => println("x+y=" + (x + y)) // 匹配第一個元素爲1,長度不限制的數組 case Array(1, _*) => println("x") case _ => println(s"Nothing") } }
運行結果以下:code
1 x+y=1 x+y=3 x Nothing
def main(args: Array[String]): Unit = { val array: Array[Any] = Array((1, 2), (2, 1), (3, 4), (1, 2, 3)) for (e <- array) { matchTuple(e) } } def matchTuple(v: Any): Unit = { v match { // 匹配1結尾 case (x, 1) => println(x) // 匹配1開頭 case (1, y) => println(y) // 匹配兩個長度的元祖 case (x, y) => println(s"x = $x, y = $y") case _ => println(s"Nothing") } }
運行結果以下:對象
2 2 x = 3, y = 4 Nothing
下面註釋掉的部分代碼等同於他的下一句。字符串
def main(args: Array[String]): Unit = { val list: List[List[Int]] = List(List(0), List(1), List(1, 2), List(1, 2, 3)) for (e <- list) { matchList(e) } } def matchList(v: List[Int]): Unit = { v match { // 匹配List(1) // case List(1) => println(v(0)) case 1 :: Nil => println(v(0)) // 匹配兩個長度的數組 // case List(x, y) => println("x+y=" + (x + y)) case x :: y :: Nil => println("x+y=" + (x + y)) // 匹配第一個元素爲1,長度不限制的數組 // case List(1, _*) => println(v(0) + "-" + v.tail) case x :: tail => println(x + "-" + tail) case _ => println(s"Nothing") }
運行結果以下:hash
0-List() 1 x+y=3 1-List(2, 3)
對象匹配是匹配對象的值,可是case裏僅僅調用Person伴生對象的apply方法建立一個對象是不行的,他還須要Person的伴生對象聲明unapply方法。
case中對比的時候,他會把Person對象傳入到unapply方法,獲得Some,而後再根據對象的屬性進行匹配。it
def main(args: Array[String]): Unit = { val list: List[Person] = List(Person("張三", 18), Person("李四", 20), Person("王五", 28)) for (e <- list) { matchPerson(e) } } def matchPerson(v: Person): Unit = { v match { case Person("張三", 18) => println(s"姓名:${v.name},年齡:${v.age}") case Person("李四", 20) => println(s"姓名:${v.name},年齡:${v.age}") case _ => println(s"Nothing") } } class Person(val name: String, val age: Int) { } object Person { def apply(name: String, age: Int): Person = new Person(name, age) def unapply(person: Person): Option[(String, Int)] = { if (null == person) { None } else { Some(person.name, person.age) } } }
若是每次對象都要像上面進行匹配,那代碼就很繁瑣了。
因此scala提供了一個樣例類,關鍵字case,上面的代碼能夠簡化成下面的:
def main(args: Array[String]): Unit = { val list: List[Person2] = List(Person2("張三", 18), Person2("李四", 20), Person2("王五", 28)) for (e <- list) { matchPerson(e) } } def matchPerson(v: Person2): Unit = { v match { case Person2("張三", 18) => println(s"姓名:${v.name},年齡:${v.age}") case Person2("李四", 20) => println(s"姓名:${v.name},年齡:${v.age}") case _ => println(s"Nothing") } } case class Person2(name: String, age: Int)
經過case關鍵字,Person2的對象就自動生成伴生對象,而且伴生對象除了生成上面的apply和unapply方法之外,還生成了toString、equals、hashCode 和 copy這些方法。若是做用在class上,那這個class就是多例的,若是做用在object上,那就是單例的。咱們能夠看到構造函數並無指定val仍是var的,他默認是val的。