一.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模式匹配的资料请关注小牛知识库其它相关文章!
主要内容:实例,实例,使用样例类,实例Scala 提供了强大的模式匹配机制,应用也非常广泛。 一个模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。 以下是一个简单的整型值模式匹配实例: 实例 object Test { def main (args : Array [String ] ) { println (matchTes
Scala 提供了强大的模式匹配机制,应用也非常广泛。 一个模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。 以下是一个简单的整型值模式匹配实例: object Test { def main(args: Array[String]) { println(matchTest(3))
本文向大家介绍浅谈Nodejs观察者模式,包括了浅谈Nodejs观察者模式的使用技巧和注意事项,需要的朋友参考一下 一、前言 Nodejs使用有些日子了,近来再回顾下其API、多使用新特性,以期有更高层次的掌握,本次API的总结区别于单纯对英文版的汉化,会多做些扩展和自己的理解,希望对大家有所帮助,先从最核心的Events开始 Nodejs的Events实现了一种观察者模式,其支持了Nodejs的
本文向大家介绍浅谈Node.js 中间件模式,包括了浅谈Node.js 中间件模式的使用技巧和注意事项,需要的朋友参考一下 中间件在 Node.js 中被广泛使用,它泛指一种特定的设计模式、一系列的处理单元、过滤器和处理程序,以函数的形式存在,连接在一起,形成一个异步队列,来完成对任何数据的预处理和后处理。 它的优点在于 灵活性 :使用中间件我们用极少的操作就能得到一个插件,用最简单的方法就能将新
本文向大家介绍浅谈C#设计模式之代理模式,包括了浅谈C#设计模式之代理模式的使用技巧和注意事项,需要的朋友参考一下 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口.根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理、远程代理、虚拟代理、缓冲代
本文向大家介绍浅谈JAVA设计模式之享元模式,包括了浅谈JAVA设计模式之享元模式的使用技巧和注意事项,需要的朋友参考一下 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。我们将通过创建 5