聊聊 scala 的模式匹配
一. 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 的话,代码会简洁清晰很多,而简洁的代码则会更容易阅读。
参考文章:
https://doc.yonyoucloud.com/doc/guides-to-scala-book/chp3-pattern-everywhere.html

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
11大Java开源中文分词器的使用方法和分词效果对比
本文的目标有两个: 1、学会使用11大Java开源中文分词器 2、对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那要用的人结合自己的应用场景自己来判断。 11大Java开源中文分词器,不同的分词器有不同的用法,定义的接口也不一样,我们先定义一个统一的接口: 从上面的定义我们知道,在Java中,同样的方法名称和参数,但是返回值不同,这种情况不可以使用重载。 这两个方法的区别在于返回值,每一个分词器都可能有多种分词模式,每种模式的分词结果都可能不相同,第一个方法忽略分词器模式,返回所有模式的所有不重复分词结果,第二个方法返回每一种分词器模式及其对应的分词结果。 在这里,需要注意的是我们使用了Java8中的新特性默认方法,并使用stream把一个map的value转换为不重复的集合。 下面我们利用这11大分词器来实现这个接口: 1、word分词器 2、Ansj分词器 3、Stanford分词器 4、FudanNLP分词器 5、Jieba分词器 6、Jcseg分词器 7、MMSeg4j分词器 8、IKAnal...
- 下一篇
丑拒!如何在Python中编写精美图形界面
在默认情况下,我们使用PyQt5创建出来的窗口和部件都是默认的样式,虽然谈不上很丑,但是也毫无美感可言。 其实,在PyQt5中,我们可以有较高的自由度来自定义窗口和各种小部件的样式,通过自定义这些样式,以达到美化图形界面的目的。 本篇文章中,我们就通过一个实际的例子,使用QSS和PyQt5的配置属性,实现图形用户界面的美化工作。 首先上效果图: 使用到的图片素材有9张音乐的封面图片: 需要素材的小伙伴可以在微信公众号回复关键词“0013”获取下载链接。 一、对界面进行布局和组件的布置 在图像界面编程中,一个好的布局有助于全局把控界面的形态,而在PyQt5中,有多种布局的方式供我们选择,比较常用的布局有以下几种: ● 表单布局:QFormLayout ● 网格布局:QGridLayout ● 水平排列布局:QHBoxLayout ● 垂直
相关文章
文章评论
共有0条评论来说两句吧...