前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Scala专题系列 (八) : 模式匹配

Scala专题系列 (八) : 模式匹配

作者头像
用户5252199
发布2022-04-18 14:00:54
8220
发布2022-04-18 14:00:54
举报
模式匹配包括一系列备选项,每个替代项以关键字大小写为单位。每个替代方案包括一个模式和一个或多个表达式,如果模式匹配,将会进行评估计算。箭头符号=>将模式与表达式分离。

模式匹配的类型分为 :

  • 常量模式匹配
  • 变量模式匹配
  • 构造器模式
  • 序列模式
  • 元组模式
  • 变量绑定模式

模式匹配 - 常量模式

所谓常量模式匹配就是在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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据技术博文 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档