Scala 中的模式匹配類似于Java中的switch語法
,但是scala 從語法中補充了更多的功能,所以更加強大
模式匹配語法中,采用match
關(guān)鍵字聲明,每個分支采用case
關(guān)鍵字進(jìn)行聲明,當(dāng)需要匹配時,會從第一個case分支開始,如果匹配成功,那么執(zhí)行相對應(yīng)的邏輯代碼,如果匹配不成功,繼續(xù)執(zhí)行下一個分支進(jìn)行判斷。如果所有的case都不匹配,那么會執(zhí)行case…分支,類似于Java中的default
語句
(1) 如果所有case都不匹配,那么會執(zhí)行case_
分支,類似于Java中的default
語句,若此時沒有case_
分支,那么會拋出MatchError
(2) 每個case中,不需要使用break 語句,自動中斷case
(3) match case 語句可以匹配任何類型,而不是字面量
(4) =>后面的代碼塊,直到下一個case 語句之前的代碼是作為一個整體執(zhí)行
,可以使用{}
括起來,也可以不括
package Scala04_moshipipei
//模式匹配基本語法
class test01_moshi {}
object test01_moshi{def main(args: Array[String]): Unit = {//1、基本語法定義
val x:Int = 10
val y:String = x match { case 1 =>"one" //如果為1那么返回的是one,中間是=>連接
case 2 =>"two"
case 3 =>"there"
case _ =>"這就是默認(rèn)情況了,0"
}//判斷x等于什么,如果x為1那么y就是one,如果x為2那么y就是two
println(y)
//2、示例;用模式匹配實現(xiàn)簡單的二元運算
val a = 25
val b = 13
def hanshu(op:Char) = op match { case '+' =>a + b
case '-' =>a - b
case '*' =>a * b
case '/' =>a / b
case '%' =>a % b
case _ =>"非法運算符"
}
println(hanshu('*'))
println(hanshu('+'))
println("\\") //傳一個字符進(jìn)去,還要進(jìn)行轉(zhuǎn)義
}
}
二、模式守衛(wèi)如果想要表達(dá)匹配某個范圍的數(shù)據(jù),就需要在模式匹配中增加條件守衛(wèi)
注意:num 就是 那個 i
,然后調(diào)用的時候傳入?yún)?shù)進(jìn)去就可以了
// 模式守衛(wèi)
//求一個整數(shù)的絕對值
def fanfga(num:Int) = num match {//num就是下面的那個i
case i if i >= 0 =>i //定義一個i,如果i大于等于0就返回i
case i if i< 0 =>-i //如果小于0 那么輸出-i,那肯定就是絕對值
}
println(fanfga(5))
println(fanfga(0))
println(fanfga(-5))
Scala 中,模式匹配可以匹配所有的字面量,包括字符串,字符,數(shù)字,布爾值等等。
推薦還是把case _
加上,因為寫的條件可能就那么幾個,要是寫錯了,就會報MatchError
//Scala 中,模式匹配可以匹配所有的字面量,包括字符串,字符,數(shù)字,布爾值等等。
//1、匹配常量
def hanshu(x:Any):String = x match {//返回值不一定非得String,其他的也可以
case 1 =>"num one" //這就是返回值
case "hello scala" =>"String hello"
case true =>"Boolen true" //連布爾類型都可以
case '+' =>"Char +"
case _ =>"" //建議還是要設(shè)置一個這個,然后條件是有限的,傳入?yún)?shù)要是沒有就報錯了
}
println(hanshu(1))
println(hanshu("hello scala"))
println(hanshu(true))
println(hanshu(0.3))
Scala 不僅僅可以匹配常量,還可以匹配數(shù)據(jù)結(jié)構(gòu),比如列表,數(shù)組.
注意:類型匹配的時候要注意,比如定義了List[String]
泛型,規(guī)定的定義的是String
類型的,但是Int類型的還是匹配上了,因為Scala 的底層有泛型擦除
,他只會匹配到是一個list,泛型會自動擦除。而數(shù)組比較特殊,它是沒有泛型擦除的,所以特別注意這兩個地方,容易出現(xiàn)Bug
package Scala04_moshipipei
//模式匹配類型
class test02_pipeileixing {}
object test02_pipeileixing{def main(args: Array[String]): Unit = {//Scala 中,模式匹配可以匹配所有的字面量,包括字符串,字符,數(shù)字,布爾值等等。
//1、匹配常量
def hanshu(x:Any):String = x match {//返回值不一定非得String,其他的也可以
case 1 =>"num one" //這就是返回值
case "hello scala" =>"String hello"
case true =>"Boolen true" //連布爾類型都可以
case '+' =>"Char +"
case _ =>"" //建議還是要設(shè)置一個這個,然后條件是有限的,傳入?yún)?shù)要是沒有就報錯了
}
println(hanshu(1))
println(hanshu("hello scala"))
println(hanshu(true))
println(hanshu(0.3))
println("================")
//2、匹配類型
def hanshu2(x:Any):String = x match { case i:Int =>"int" + i //相當(dāng)于前面規(guī)定了這個變量必須的是Int類型的才能匹配上
case i:String =>"String," + i
case list: List[String] =>"list:" + list //連List類型都可以定義
case array:Array[Int] =>"現(xiàn)在是第"+array.mkString(",")+"圈" //因為數(shù)組直接輸出是引用,所以要用mkString方法輸出
case a =>"Something else:" + a //這是兜底的方法,要拿到值的話就不能用 _ ,必要要設(shè)置一個變量
}
println(hanshu2(35))
println(hanshu2("hello"))
println(hanshu2(List("hi","hello")))
println(hanshu2(List(2,23)))
println(hanshu2(Array("hi","hello")))
println(hanshu2(Array(2,23)))
}
}
Scala 模式匹配,匹配數(shù)組非常強大,可以進(jìn)行各種模糊的匹配,比如可以匹配必須是三個元素,或者中為1的三個元素的數(shù)組。
//3、匹配數(shù)組
for (arr<- List(
Array(0),
Array(1,0),
Array(0,1,0),
Array(1,1,0),
Array(2,3,7,15),
Array("hello",20,30)
)){ val result = arr match { case Array(0) =>"0"
case Array(1,0) =>"1,0"
case Array(x,y) =>"Array:" + x + y //相當(dāng)于可以進(jìn)行模糊查詢,匹配兩元素數(shù)組
case Array(0,_*) =>"以0開頭的數(shù)組"
case Array(x,1,z) =>"中間為1的三元素數(shù)組"
case _ =>"兜底的方法"
}
println(result)
}
列表的匹配有兩種方式,第一種和數(shù)組的匹配的方式是一樣的,
第二種是:case first :: second :: rest =>println(s"first:${first} second:${second} rest
,rest是列表,first是第一個元素,second是第二個元素,表示這個列表中至少要有兩個元素才能匹配到。列表的這種匹配方式非常常用。
//方式一
for(list<- List(
List(0),
List(1,0),
List(0,0,0),
List(1,1,0),
List(88),
List("hello")
)){ val result2 = list match {//這個list就是前面的那個list
case List(0) =>"0"
case List(x,y) =>"List(x,y):" + x + "," + y //這個x,y就是兩個數(shù)的那個列表
case List(0,_*) =>"List(0,...)" //必須以0開頭的列表。后面的個數(shù)不限*是通配符
case List(a) =>"List(a)" //表示list里面只有一個元素
case _ =>"something else"
}
println(result2)
}
println("=====================")
//方式二
//這種方式在列表匹配里面非常常用
val list = List(1,2,5,7,24)
val list1 = List(24)
list1 match { case first :: second :: rest =>println(s"first:${first} second:${second} rest ${rest}") //相當(dāng)于rest是一個列表,第一個元素是first,第二個元素是second
case _ =>println("something else")
}
5、匹配元組元組的匹配跟之前的列表和數(shù)組的匹配是非常相似的
for(tuple<- List(
(0,1),
(0,0),
(0,1,0),
(1,23,56),
("hello",true,0.5)
)){ val result = tuple match {case (a,b) =>println(s"${a},${b}") //這就是一個二元組
case (0,_) =>println("0,_") //表示第一個元素是0,第二個元素不做要求的一個二元組
case (a,1,_) =>println("a,1,_"+ a) //表示中間那個元素必須是1,最后一個元素不關(guān)心
case _ =>"something"
}
println(result)
}
除此之外很有很多操作,很靈活
package Scala04_moshipipei
//元組匹配的擴展,元組的匹配是有一點特殊的,是很靈活的
class test03_MatchTuple {}
object test03_MatchTuple{def main(args: Array[String]): Unit = {//1、在變量聲明時匹配
val (x,y) = (10,"hello")
println(s"${x},${y}")
val List(first,second,_*) = List(23,15,9,78) //把first賦值給了23,吧second賦值給了15
println(s"first:${first},second:${second}")
val fir :: se :: rest = List(23,15,9,78) //想要吧后面兩個賦值給一個,那么還是::這種方法
println(s"first:${fir},second:${se},rest:${rest}")
//2、for推導(dǎo)式中進(jìn)行模式匹配
val list:List[(String,Int)] = List(("a",12),("b",35),("c",27),("a",24))
for (i<- list){//使用增強for循環(huán)進(jìn)行遍歷
println(i._1 + " " + i._2)
}
//2.2 將List的元素直接定義為元組,對變量賦值
for((word,count)<- list){ println(word+ " " +count) //直接輸出就可以了
}
println("=============")
//2.3 可以不考慮某個位置的變量,只遍歷key或者value
for((word,_)<- list){ println(word) //這樣就得到的全都是key了
}
println("==================")
//2.4 指定某個位置的值必須是多少
for (("a",count)<- list){ println(count) //把所有key是"a"對應(yīng)的value值都打印出來
}
}
}
6、匹配對象及樣例類
(1) 基本語法class User(val name:String,val age:Int)
這個可以說是一個非常強大的功能,通過伴生對象里面的值來進(jìn)行匹配,伴生對象里面要有apply
方法,還要有unapply
方法,用來對對象屬性進(jìn)行拆解,不然會報錯。
步驟簡單來說就是,首先定義一個類,然后定義它的伴生對象,然后再伴生對象里面實現(xiàn)apply
方法,然后還要是先unapply
方法
package Scala04_moshipipei
class test04_Object {}
object test04_Object{def main(args: Array[String]): Unit = {val student = new Student("aex",18)
//針對對象實例的內(nèi)容進(jìn)行匹配
val result = student match { case Student("aex",18) =>"aex,18"
case _ =>"else"
}
println(result)
}
}
//定義類
class Student(val name:String,val age:Int){}
//定義一個伴生對象
object Student {def apply(name: String, age: Int): Student = new Student(name, age)
//必須實現(xiàn)一個unapply 方法,用來對對象屬性進(jìn)行拆解,這個方法名也是固定的了的,只能為這個
def unapply(student: Student): Option[(String, Int)] = {if (student == null) { None
} else { Some(student.name, student.age) //這樣就拆分出來了
}
}
}
(2) 優(yōu)化case樣例類上面那種方式,雖然實現(xiàn)了,但是太繁瑣了違背了scala簡潔的定義,所以有了樣例類,樣例類的定義非常簡單,直接在類的前面加上case
關(guān)鍵字
例如:case class Student1(val name:String,val age:Int){}
定義了樣例類之后,就相當(dāng)于自動實現(xiàn)了伴生類,apply方apply
法和unapply
方法,然后可以直接進(jìn)行對象匹配了
package Scala04_moshipipei
//樣例類,對象匹配的簡化
class test05_yanglilei {}
object test05_yanglilei{def main(args: Array[String]): Unit = {val student = new Student1("aex",19)
val result = student match { case Student1("aex",19) =>"aex,18"
case _ =>"沒有可以進(jìn)行匹配的"
}
println(result)
}
}
//定義樣例類 前面加一個case關(guān)鍵字就可以了
//定義了樣例類,就相當(dāng)于自動實現(xiàn)了伴生對象,apply方法和unapply方法
case class Student1(val name:String,val age:Int){}
7、偏函數(shù)式的模式匹配(了解)偏函數(shù)也是函數(shù)的一種,通過偏函數(shù)我們可以方便的對輸入?yún)⒆龈_的檢查。例如該偏函數(shù)的輸入類型為List[Int],而我們需要的是第一個元素是0的集合,這就是通過模式匹配實現(xiàn)的。
偏函數(shù)定義
package Scala04_moshipipei
//偏函數(shù)
class test06_PartialFunction {}
object test06_PartialFunction{def main(args: Array[String]): Unit = {val list = List(("a",12),("b",35),("c",27),("a",13)) //二元組
//1、map轉(zhuǎn)換,實現(xiàn)key不變,value變成原來的2倍
val newList = list.map(a =>(a._1,a._2*2)) //下滑1第一個元素不變,第二個元素*2
println(newList)
//2、模式匹配也可以做這個操作,模式匹配對元組元素賦值,實現(xiàn)功能
val newList2 = list.map(
a =>{a match { case (word,count) =>(word,count*2) //直接這樣就賦值了
case _ =>"沒有匹配的"
}
}
)
println(newList2)
//3、省略lambda 表達(dá)式的寫法,進(jìn)行簡化
val newList3 = list.map{ case (word,count) =>(word,count*2)
}
println(newList3)
//偏函數(shù)的應(yīng)用,求絕對值
//對輸入數(shù)據(jù)分為不同的情形:正,負(fù),0
val zheng:PartialFunction[Int,Int] = {//輸入的類型是Int,返回的類型也是一個Int
case x if x >0 =>x
}
//這是負(fù)數(shù)的偏函數(shù)
val fushu:PartialFunction[Int,Int] = {//輸入的類型是Int,返回的類型也是一個Int
case x if x< 0 =>-x
}
//這是為0的情況
val zero:PartialFunction[Int,Int] = {//輸入的類型是Int,返回的類型也是一個Int
case 0 =>0
}
def abs(x:Int):Int = (zheng orElse fushu orElse zero ) (x) //前面是作為一個整體
println(abs(-5))
println(abs(0))
println(abs(35))
}
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁題目:Scala模式匹配-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://chinadenli.net/article4/descie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站內(nèi)鏈、定制網(wǎng)站、面包屑導(dǎo)航、網(wǎng)站營銷、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容