这里通过一些我用过的例子来举例模式匹配最简单的用法,为什么说是最简单的用法,因为暂且我只会这些。
Scala中的模式匹配类似于Java中的switch
1.
val oper = '#'
val n1 = 20
val n2 = 10
var sum = 0
oper match{
case '+'=>sum = n1 + n2
case '-'=>sum = n1 - n2
case '*'=>sum = n1 * n2
case '/'=>sum = n1 / n2
case _ => println("没有匹配到东西")
}
println("sum="+sum)
遇到“+”号匹配“+”,遇到“-”号匹配“-”,没有遇到合适的匹配就匹配默认的选项
想要匹配到某个范围内的数据时,需要在匹配模式中增加条件守卫
for (ch <- "+-3!") {
var sign = 0
var digit = 0
ch match {
case '+' => sign = 1
case '-' => sign = -1
case _ if ch.toString.equals("3") => digit = 3
case _ => sign = 2
}
println(ch + " " + sign + " " + digit)
}
3.
当默认匹配放到match首行时,只会执行默认匹配
for(ch<-"+-3!"){
var sign = 0
var digit = 0
ch match{
case _=>sign=1
case '+'=>sign=2
case '-'=>sign=3
}
println("sign="+sign+" "+"digit="+digit+" "+"ch="+ch)
}
只执行默认的值,sign一直都是1
4.
模式中的变量,如果case关键字后面跟上变量名,match前的表达式的值就会赋给那个变量
val ch = 'V'
ch match{
case '+'=>println("ok")
case mychar=>println("ok"+mychar)
case _ => println("ok")
}
执行的就是第二条语句
5.
类型匹配,可以匹配对象的任意类型,这样避免了isInstanceOf和asInstanceOf方法的使用
val a = 7
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 result = obj match{
case a:Int => a
case b:Map[String,Int]=>"一个字符串-数字的Map集合"
case c:Map[Int,String]=>"一个数字-字符串的Map集合"
case d:Array[String]=>"一个字符串数组"
case e:Array[Int]=>"一个数字数组"
case f:BigInt=>Int.MaxValue
case _=>"无"
}
println(result)
a=7,匹配的应该是Array[String,Int],没有与之合适的匹配项,返回默认匹配“无”
匹配数组:
Array(0):匹配只有一个元素,且为0的数组
Array(x,y):匹配有两个元素,且将两个元素赋值给x,y;等等:Array(x,y,z)赋值给三个元素
Array(0,_*):匹配以0开头的数组
for(arr<-Array(Array(0),Array(1,0),Array(0,1,0),Array(1,1,0),Array(1,1,0,1))){
val result = arr match{
case Array(0)=>"0"
case Array(x,y)=>x+"="+y
case Array(0,_*)=>"匹配的数组以0开头"
case _=>"无"
}
println("result="+result)
}
匹配列表
for(list<-Array(List(0),List(1,0),List(0,0,0),List(1,0,0))){
val result = list match{
case 0 :: Nil => "0"
case x :: y ::Nil=> x +" "+ y
case 1 :: tail => " 以1开头的多个元素的list"
case 0 :: tail => " 以0开头的多个元素的list"//匹配List(0,*)以0开始的多个元素List
case _=> "无"
}
println(result)
}
8.
匹配元组
for (pair<-Array((0,1),(1,0),(2,1),(1,0,2))){
val result=pair match{
case (0,_)=>"0开头的元组"
case (y,0)=>y
case (a,b)=>(b,a)
case _=>"无"
}
println(result)
}
9.
对象匹配
匹配成功:
1.case中对象的unapply方法(对象提取器)返回Some集合则为匹配成功
2.返回none集合则为匹配失败
object Square{
def unapply(z:Double):Option[Double]=Some(math.sqrt(z))
def apply(z:Double):Double=z*z
}
val number:Double=Square(64.0) //先执行apply,再执行unapply
number match{
case Square(n)=>println(n) //当case后面跟的是Square这个object对象时,会默认调用unapply方法
case _=>println("无")
}
先执行apply方法,之后执行unapply方法,返回值是64
对象匹配举例
object Names{
def unapplySeq(str:String):Option[Seq[String]]={ //当case后面的对象提取器方法的参数为多个,默认调用def unapplySeq()方法
if(str.contains(",")){
Some(str.split(","))
}else{
None
}
}
}
val namesString = "asd1,asd2,asd3"
namesString match{
case Names(first,second,third)=>{
println("下面打印的是三个人的名字")
println(s"$first,$second,$third")
}
case _=>println("无")
}
11.
(key,value)的匹配
val map = Map("A"->1,"B"->0,"C"->3)
for((k,v)<-map){
println(k+"->"+v)
}
for((k,v)<-map){
println(k+"->"+0)
}
for((k,v)<-map if v==0){
println(k+"->"+v)
}