浅谈Scala模式匹配

所属分类: 软件编程 / 其它相关 阅读数: 818
收藏 0 赞 0 分享

一.scala模式匹配(pattern matching)

pattern matching可以说是scala中十分强大的一个语言特性,当然这不是scala独有的,但这不妨碍它成为scala的语言的一大利器。

scala的pattern matching是类似这样的,

e match {
 case Pattern1 => do Something
 case Pattern2 if-clause => do others
 ...
}

其中,变量e后面接一个match以及一个代码块,其中每个case对应一种可能回匹配的类型,如果匹配成功则执行=>后面的代码。

我们可以用一个具体一些的例子来看看模式匹配是怎么工作的:

case class Player(name: String, score: Int)
def printMessage(player: Player) = player match {
 case Player(_, score) if score > 100000 =>
  println("Get a job, dude!")
 case Player(name, _) =>
  println("Hey, $name, nice to see you again!")
}

看起来有点类似于其他语言的switch,但其实还是有很大的不同的。

以java的switch为例,java的switch仅仅会做一些基本类型的匹配,然后执行一些动作,并且是没有返回值的。

而scala的pattern matching match则要强大得多,除了可以匹配数值,同时它还能匹配类型。

def parseArgument(arg: String) = arg match {
  //匹配值
  case "-h" | "--help" => displayHelp
  case "-v" | "--version" => displayVerion
  case whatever => unknownArgument(whatever)
}
def f(x: Any): String = x match {
  //匹配类型
  case i:Int => "integer: " + i
  case _:Double => "a double"
  case s:String => "I want to say " + s
}

同时pattern matching是有返回值的,比如上面的match,它返回的就是一个Unit。我们也可以修改上面的代码让它返回一个字符串:

case class Player(name: String, score: Int)
def message(player: Player) = player match {
 case Player(_, score) if score > 100000 =>
  "Get a job, dude!"
 case Player(name, _) =>
  "Hey, $name, nice to see you again!"
}

值得一提的是,pattern matching 返回值是由第一个匹配的模式中的代码块决定的。

二. 为什么要用pattern matching

看到这里你会发现一个问题,pattern matching不是和if else差不多吗?那为什么还要使用pattern matching呢?

首先我们需要明白,模式匹配其实本质上是提供一个方便的解构(Destructuring)数据结构的方式,以scala为例,pattern matching其实用到了scala中提取器的功能,提取器其实就是类中的unapply()方法。

trait User {
 def name: String
}
class FreeUser(val name: String) extends User
object FreeUser {
 //提取器
 def unapply(user: FreeUser): Option[String] = Some(user.name)
}
 val user: User = new FreeUser("Daniel")
 user match {
  case FreeUser(name) => println("it match here" + name)
  case _ => println("not me")
 }

明白了模式匹配的本质你就会直到,其实if else只是pattern matching中的一个典型的用法,但并非它的全部。

同时,pattern matching允许你解耦两个并不真正属于彼此的东西,也使得你的代码更易于测试。比如上面的match部分的代码我们可以写成下面这样:

 val user: User = new FreeUser("Daniel")
 //将返回结果存在一个常量中
 val message = user match {
  case FreeUser(name) => "it match here" + name
  case _ => "not me"
 }
 //可以随意使用该常量,实现解耦
 println(message)

这样会赋予代码更多的灵活性,同时也更加方便做进一步操作。

而以可读性的角度来说,使用一大堆的if else代码无疑是比较难看的,而如果使用pattern matching的话,代码会简洁清晰很多,而简洁的代码则会更容易阅读。

以上就是浅谈Scala模式匹配的详细内容,更多关于scala模式匹配的资料请关注脚本之家其它相关文章!

更多精彩内容其他人还在看

Idea 无法引用类问题解决办法

这篇文章主要介绍了 Idea 无法引用类问题解决办法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Unity3D中shader 轮廓描边效果实现代码

这篇文章主要介绍了Unity3D中shader 轮廓描边效果的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

8个基于Lucene的开源搜索引擎(推荐)

Lucene是一种功能强大且被广泛使用的搜索引擎,以下列出8种基于Lucene的搜索引擎,你可以想象他们有多么强大
收藏 0 赞 0 分享

计算机二级如何一次性通过?给NCRE焦躁心情降温!

计算机二级到现阶段应该如何备考,该听什么课?该针对哪些考点重点学习,这些都要做到心里有数,有计划性。这篇文章为大家分享了计算机二级备考技巧,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

HBuilder打包App方法(图文教程)

下面小编就为大家带来一篇HBuilder打包App方法(图文教程)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

深入理解Scala函数式编程过程

这篇文章主要介绍了深入理解Scala函数式编程过程的相关资料,希望通过本文能帮助到大家,让大家学习理解这部分内容,需要的朋友可以参考下
收藏 0 赞 0 分享

权限控制之粗粒度与细粒度概念及实现简单介绍

这篇文章主要介绍了权限控制之粗粒度与细粒度概念及实现简单介绍,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Hbuilder配置Avalon和Vue指令提示的方法详解

HBuilder是DCloud(数字天堂)推出的一款支持HTML5的Web开发IDE,下面这篇文章主要给大家介绍了关于Hbuilder如何配置Avalon和Vue指令提示的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面来一起看
收藏 0 赞 0 分享

Hbuilder连远程接服务器上传代码的图文教程

下面小编就为大家分享一篇Hbuilder连远程接服务器上传代码的图文教程,具有很好的参考价值,一起跟随小编过来看看吧,希望对大家有所帮助
收藏 0 赞 0 分享

App开发建议技巧

有同学问我,对应用开发你有没有值得注意或小技巧的地方可以分享的。比如适配、优化、排查错误什么的。鸡排把自己的总结笔记整理出来了。供大家参考
收藏 0 赞 0 分享
查看更多