模式匹配和樣例類
模式匹配
Scala沒有Java中的switch case,它有一個更加強大的模式匹配機制,可以應(yīng)用到很多場合。
Scala的模式匹配可以匹配各種情況,比如變量的類型、集合的元素、有值或無值。
模式匹配的基本語法結(jié)構(gòu):變量 match { case 值 => 代碼 }
模式匹配match case中,只要有一個case分支滿足并處理了,就不會繼續(xù)判斷下一個case分支了,不需要使用break語句。這點與Java不同,Java的switch case需要用break阻止。如果值為下劃線,則代表不滿足以上所有情況的時候如何處理。
模式匹配match case最基本的應(yīng)用,就是對變量的值進行模式匹配。match是表達式,與if表達式一樣,是有返回值的。
除此之外,Scala還提供了樣例類,對模式匹配進行了優(yōu)化,可以快速進行匹配。
字符和字符串匹配
package hhb.cn.part07
import scala.util.Random
object MatchDemo {
def main(args: Array[String]): Unit = {
//對字符進行模式匹配
val carStr = '6'
carStr match {
//只要有一個匹配上就會直接返回,不需要break。
case '+' => println("11111111111")
case '-' => println("22222222222")
case '*' => println("33333333333")
case '/' => println("44444444444")
//這個表示上面的都沒有匹配上,輸出other,類似Java中default
case _ => println("other")
}
//對字符串進行模式匹配
val arr = Array("Hadoop", "Zookeeper", "Spark", "Scala")
val project = arr(Random.nextInt(arr.length))
println(project)
project match {
case "Hadoop" => println("this is Hadoop")
case "Zookeeper" => println("this is Zookeeper")
case "Spark" => println("this is Spark")
case _ => println("Other")
}
}
}
守衛(wèi)式匹配
//守衛(wèi)式匹配,添加if 判斷
val c = '/'
val num = c match {
case '+' => 1
case '-' => 2
case _ if c.equals('*') => 3
case _ => 4
}
println(num)
匹配類型
Scala的模式匹配還有一個強大的功能,它可以直接匹配類型,而不是值。這一點是Java的switch case做不到的。
匹配類型的語法:case 變量 : 類型 => 代碼,而不是匹配值的“case 值 => 代碼”這種語法。
//匹配類型語法: case 變量 : 類型 => 代碼
def typeMatch(x: Any): Int = {
x match {
case x: String => println("這是一個字符串類型")
1
case x: Int => println("這是一個整型類型")
2
case x: Boolean if x == false => println("這是布爾類型的false")
3
case x: Array[Int] => println("這是一個整型數(shù)組")
4
case _ => println("不知道是什么類型")
5
}
匹配數(shù)組、元組、集合
package hhb.cn.part07
object MatchCollection {
def main(args: Array[String]): Unit = {
//對Array數(shù)組進行匹配,分別匹配:帶有指定個數(shù)元素的數(shù)組、帶有指定元素的數(shù)組、以某個元素開頭的數(shù)據(jù)
// val array = Array(1, 3, 5, 7, 9) // 這是一個其他數(shù)組
//val array = Array(1, 3, 5) //這是一個指定長度為3的數(shù)組,并且第一個元素為1,x y 分別為 :3 5
// val array = Array(1) //這是一個指定長度只有1的數(shù)組,而且元素就是1
val array = Array(2) // 這是一個其他數(shù)組
array match {
case Array(1, x, y) => println(s"這是一個指定長度為3的數(shù)組,并且第一個元素為1,x y 分別為 :$x $y")
case Array(1) => println("這是一個指定長度只有1的數(shù)組,而且元素就是1")
case Array(1, _*) => println("這是一個以1開頭的數(shù)組")
case _ => println("這是一個其他數(shù)組")
}
//對List集合進行匹配,分別匹配:帶有指定個數(shù)元素的列表、帶有指定元素的列表、以某個元素開頭的列表、以某個元素結(jié)尾
// val list = List(1, 3, 4, 5) // 這是一個以1開頭的元素
// val list = List(1, 3) // 這個一個有指定個數(shù)元素的列表,1 3
// val list = List(1) // 這是一個指定長度只有1的列表,而且元素就是1
val list = List(2, 4, "s") // 其他
list match {
case x :: y :: Nil => println(s"這個一個有指定個數(shù)元素的列表,$x $y")
case 1 :: Nil => println("這是一個指定長度只有1的列表,而且元素就是1")
case 1 :: tail => println("這是一個以1開頭的元素")
// case head :: 2 => println("這是一個以2結(jié)尾的元素")
case _ => println("其他")
}
//對元組進行匹配
var tuple = (2, 3, 2)
tuple match {
//以1開頭,包含三個元素的元組
case (1, x, y) => println(s"$x $y")
//以1結(jié)尾,包含三個元素的元組
case (x, _, 1) => println(s"$x ")
case _ => println("其他")
}
}
}
樣例類
case class樣例類是Scala中特殊的類。當(dāng)聲明樣例類時,以下事情會自動發(fā)生:
- 主構(gòu)造函數(shù)接收的參數(shù)通常不需要顯式使用var或val修飾,Scala會自動使用val修飾
- 自動為樣例類定義了伴生對象,并提供apply方法,不用new關(guān)鍵字就能夠構(gòu)造出相應(yīng)的對象
- 將生成toString、equals、hashCode和copy方法,除非顯示的給出這些方法的定義
- 繼承了Product和Serializable這兩個特質(zhì),也就是說樣例類可序列化和可應(yīng)用Product的方法
case class是多例的,后面要跟構(gòu)造參數(shù),case object是單例的。
此外,case class樣例類中可以添加方法和字段,并且可用于模式匹配。
package hhb.cn.part07
class Amount
//樣例類中主構(gòu)造器的參數(shù)默認用val修飾
//樣例類中自動生成apply方法
case class Test() extends Amount
case class Dollar(value: Double) extends Amount
case class Currency(value: Double, unit: String) extends Amount
case object Nothing extends Amount
object CaseClassDemo {
def main(args: Array[String]): Unit = {
judgeIdentity(Dollar(10.0))
judgeIdentity(Currency(10.0, "123"))
judgeIdentity(Nothing)
judgeIdentity(Test())
}
/**
* 樣例類匹配
*
* @param amount
*/
def judgeIdentity(amount: Amount): Unit = {
amount match {
case Dollar(value) => println("Dollar類型")
case Currency(value, unit) => println("Currency類型")
case Nothing => println("Nothing類型")
case Test() => println("test")
}
}
}
Option與模式匹配
Scala Option選項類型用來表示一個值是可選的,有值或無值。
Option[T] 是一個類型為 T 的可選值的容器,可以通過get()函數(shù)獲取Option的值。如果值存在,Option[T] 就是一個 Some。如果不存在,Option[T] 就是對象 None 。
Option通常與模式匹配結(jié)合使用,用于判斷某個變量是有值還是無值。
object OptionDemo {
val map: Map[String, Int] = Map("a" -> 1, "b" -> 2, "c" -> 3)
def getScore(name: String): Int = {
val score = map.get(name)
score match {
//如果socre有值
case Some(score) => score
//如果score沒有值
case None => -1
}
}
def main(args: Array[String]): Unit = {
println(getScore("a"))
println(getScore("d"))
}
}
