一、什么是模式匹配
模式匹配指检查某个值(value)是否匹配某一个模式的机制,是 Scala非常重要、非常强大的功能,它不仅可以匹配值,还能够匹配类型等
语法: 选择器 match { case 备选项 }
Scala中的 match表达式类似 Java中的 switch语句, switch的 case语句可以处理 int、 short、byte、char类型的值,但是不能处理 long,String等类型。 Scala中任何类型都能当作比较用的样本( case),另外每个备选项最后不需要 break因为 break是隐含的,防止因为疏忽从一个选择落入另一个中。
二、匹配模式种类
2.1 通配模式
通配模式 (_) 能匹配任意对象,即全匹配。应该保证最少一个模式匹配,否则会报 scala.MatchError 异常。通常情况下需要添加一个 全匹配 **(_)**避免出现MatchError
示例:
expr match {
case 1=>println("one")
case 2=>println("two")
case _=>
}
通配模式还可以用来忽略对象中不关心的部分
示例:只匹配元祖中的以一个元素
(1,2) match {
case (x,_)=>println(x) //不关心第二个元素
}
//1
2.2 常量模式
常量模式仅匹配自身,任何字面量都可用做常量
示例:
def result(x:Any)=x match{
case 5=>"five"
case true=>"truth"
case "hello"=>"hi!"
case Nil=>"the empty list"
case _=>"something else"
}
2.3 变量模式
变量模式类似于通配模式,可以匹配任意对象。不过与通配符不同的是,Scala将变量绑定在匹配的对象上,随后可以使用该变量操作对象。
示例:
val expr=10
expr match {
case 0=>println("zero")
case x=>println(x) //变量模式
}
//10
2.4 构造器模式
检查对象是否为该名称的样本类实例,并提取构造参数绑定到指定变量中
2.4.1样例类的模式匹配
样例类中,自动实现了unapply()方法(提取器),用于将对象分解为用以匹配模式的片段,即该方法接受一个实例对象,返回最初创建它所用的参数
//定义一个样例类Student
case class Student(name:String,age:Int)
object CaseClassMatchDemo{
def main(args: Array[String]): Unit = {
//定义一个样例类的匹配模式
def matchTest04(x:Student)=x match{
case Student(name,19) =>println(name+"的年龄是19") //指定匹配Student的年龄是19
case Student("Tom",age) =>println("Tom,的年龄是"+age) //指定匹配Student的姓名是 "Tom"
case Student(name,age) =>println(name,age) //全匹配,f返回一个元祖,有包含关系大的范围放后面
case _ =>println("no matches")
}
val stu1: Student = Student("zhangsan", 19) //样例类实现apply方法,不需要new关键字
matchTest04(stu1) //zhangsan的年龄是19
matchTest04(Student("Tom",20)) //Tom的年龄是19
matchTest04(Student("lisi",20)) //(lisi,20)
}
}
2.4.2非样例类的模式匹配
非样例类的模式匹配前提是需要实现提取器
//定义一个普通类
class Student(n:String,a:Int){
//定义成员变量
var name:String = n
var age:Int = a
}
object Student{
def apply(n: String, a: Int): Student = new Student(n, a)
def unapply(arg: Student): Option[(String, Int)] = {
//实现提取器的逻辑代码
if(arg == null) None else Some(arg.name,arg.age)
}
}
object MatchDemo03 extends App {
//定义非样式类模式匹配
def matchTest05(x:Student)=x match {
case Student(name,age) if age <20 => println("young")
case Student(name,age) if age >50 => println("old")
case _ => println("undefine")
}
matchTest05(Student("zhangsan",18)) //young
matchTest05(Student("lisi",52)) //old
}