模式匹配的类型分为 :
- 常量模式匹配
- 变量模式匹配
- 构造器模式
- 序列模式
- 元组模式
- 变量绑定模式
模式匹配 - 常量模式
所谓常量模式匹配就是在case后面跟着的是常量,如同java中的swich语句
实例 :
代码语言:javascript复制object Demo{
def main(args:Array[String]){
matchTest(1)
matchTest("two")
}
def matchTest(x:Any):Any = x.match{
case 1 => "one"
case "two" => 2
case _ => 0
}
}
上面例子中,创建一个单例Demo,里面包含一个函数matchTest,并且参数类型是Any(scala中所有类的超类,表示任意类型), 注意看函数体 x = match{ case 1 => "one" } 这个就是scala中模式匹配的语法结构, 首先变量.match(选择器) 后面跟着一个花括号, 括号里面case指定的匹配项 , 而 => 右面指定的是表达式 , 在语句中 case _ 等同于java中swich语句的default ,如果匹配项都不符合要求,那么就返回一个默认值
模式匹配 - 变量模式
所谓常量模式匹配就是在case后面跟着的是变量
实例 :
代码语言:javascript复制object Demo{
def main(args:Array[String]){
matchTest(1)
matchTest("two")
}
def matchTest(x:Any):Any = x.match{
case x if(x == "1") => "one"
case x if(x =="two") => 2
case _ =>
}
}
变量匹配,匹的是case语句后面接的是scala变量,如case x if(x == "1") => x等,在使用时一般会加守卫条件(if(...)在模式匹配中就是一个守卫,类型是一个boolean),当然也可以像case x => x这样使用,它会匹配任何输入的合法变量 , 最后case _ => 等于一个default
模式匹配 - 构造器模式
构造器模式匹配直接在case语句后面接类构造器,匹配的内容放置在构造器参数中。
代码语言:javascript复制case class Person(name : String,age : Int) // 定义一个样板类,下面会有样板类的具体介绍.
object Demo{
def main(args:Array[String]){
getPerson("liubin",24)
}
def getPerson(p:Person) = p.match{
case Person(name,age) => name " , " age
case _ => "other"
}
}
在声明样例类时,下面的过程自动发生了:
- 构造器的每个参数都成为val,除非显式被声明为var,但是并不推荐这么做;
- 在伴生对象中提供了apply方法,所以可以不使用new关键字就可构建对象;
- 提供unapply方法使模式匹配可以工作;
- 生成toString、equals、hashCode和copy方法,除非显示给出这些方法的定义。
模式匹配-序列化模式
序列模式用于匹配如数组Array、列表List、Range这样的线性结构集合,其实原理也是通过case class起作用的。
代码语言:javascript复制object SequencePattern{
def main(args:Array[String]) :Unit = {
val list = List("spark","Hive","SparkSQL")
val arr = Array("SparkR","Spark Streaming","Spark MLib")
def pattern(p : Any) = p match {
//序列模式匹配,_*表示匹配剩余内容,first、second匹配数组p中的第一、二个元素
case Array(x,y,_*) => x "," y
//_匹配数组p的第一个元素,但不赋给任何变量
case List(_,y,_*) => y
case _ => "Other"
}
}
}
上述实例实例中,第一个模式匹配Array中第一个和第二个元素,以及后面的所有元素,_*表示剩余内容,第二模式匹配List中的第二个元素, _ 表示匹配List中的第一个元素,但是不赋值给变量
模式匹配-元组模式
元组是一种类似于集合的存储结构,不过集合是可变的,元组是不可变的,元组的声明方式:val t = new Tuple3(1,“2”,’3’)上面就是声明了一个Tuple3[Int,String,Char]类型的元组,元组的访问可以用t._1来访问第一个元素,依次类推,元组中最多可有22个元素,如果元素个数大于22,就只能使用集合了。
元组模式用于匹配scala中的元组内容,用于匹配元组类型的变量内容。
代码语言:javascript复制object TuplePattern{
def main(args:Array[String]) :Unit = {
val t = (“1”,“2”,3)
def pattern(t : Any) = t match {{
case (one,_,_) => one
case _ => "Other"
}
println(pattern(t))
}
}
上述代码中,
//_*不适合用于元组,只适用于序列
模式匹配-类型模式
类型模式即根据参数的类型来匹配表达式
代码语言:javascript复制object Demo{
def main(args:Array[String]){
matchTest(1)
}
def matchTest(x:Any):Any = x.match{
case s:String => "String"
case x:Int => “Int”
case _ => 0
}
}
在上面代码中,模式匹配到的值被当作String绑定到了s中,而在第二个模式中,值被当作Int绑定到x中;
当在匹配类型的时候,必须给出一个变量名,否则将会拿对象本身来匹配。
匹配是发生在运行时,Java虚拟机中泛型的类型信息时被擦掉的,因此不能用类型来匹配特定的Map 类型
比如:
case m:Map[String,Int] => … // 是不可行的
可以匹配一个通用的映射
caase m:Map[_,_] => ….
模式匹配分类总结:
通配模式(_):匹配任意对象,它被用作默认的“全匹配(catch-all)”的备选项
常量模型:仅匹配自身,任何字面量都可以用作常量
变量模式:类似于通配模式,它可以匹配任意对象。与通配符(_)不同的是,Scala把变量绑定在匹配的对象上。
构造器模式:提供了深度匹配(deep match),如果备选项是样本类,那么构造器模式首先检查对象是否为该备选项的样本类实例,然后检查对象的构造器参数是否符合额外提供的模式。
序列模式:可以像匹配样本类那样匹配如List或者Array这样的序列类型。
元组模式:匹配元祖
类型模式:匹配变量的类型
Option 类型
Option类型在Scala程序中经常使用,可以将其与Java中可用的null值进行比较,表示null值。 例如,java.util.HashMap的get方法返回存储在HashMap中的值,如果没有找到值,则返回null。
假设我们有一种基于主键从数据库中检索记录的方法。
def findPerson(key: Int): Option[Person]
Scala
如果找到记录,该方法将返回Some [Person],如果没有找到该记录,则返回None