一.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

https://www.zhihu.com/question/30354775


推荐阅读:

从分治算法到 MapReduce

大数据存储的进化史 --从 RAID 到 Hdfs

scala模式匹配详细解析的更多相关文章

  1. (转)linux应用之test命令详细解析

    linux应用之test命令详细解析 原文:https://www.cnblogs.com/tankblog/p/6160808.html test命令用法. 功能:检查文件和比较值 1)判断表达式 ...

  2. java类生命周期详细解析

    (一)详解java类的生命周期 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前 ...

  3. springmvc 项目完整示例06 日志–log4j 参数详细解析 log4j如何配置

    Log4j由三个重要的组件构成: 日志信息的优先级 日志信息的输出目的地 日志信息的输出格式 日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重要程度 ...

  4. include_path详细解析

    include_path详细解析     原文地址:http://www.laruence.com/2010/05/04/1450.html 1.php默认的包含路径为 .;C:\php\pear 即 ...

  5. Intent的详细解析以及用法

    Intent的详细解析以及用法      Android的四大组件分别为Activity .Service.BroadcastReceiver(广播接收器).ContentProvider(内容提供者 ...

  6. C++多态的实现及原理详细解析

    C++多态的实现及原理详细解析 作者: 字体:[增加 减小] 类型:转载   C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型 ...

  7. 对MySQL DELETE语法的详细解析

    以下的文章主要描述的是MySQL DELETE语法的详细解析,首先我们是从单表语法与多表语法的示例开始的,假如你对MySQL DELETE语法的相关内容十分感兴趣的话,你就可以浏览以下的文章对其有个更 ...

  8. 转:二十一、详细解析Java中抽象类和接口的区别

    转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...

  9. 单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式

    单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式     一 表结构如下:  万行 CREATE TABLE t_audit_operate_log (  Fid b ...

随机推荐

  1. mybatis框架(1)---mybatis入门

    mybatis入门   MyBatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了goog ...

  2. 全网最详细的最新稳定OSSEC搭建部署(ossec-server(CentOS6.X)和ossec-agent(CentOS6.X))(图文详解)

    不多说,直接上干货! 前言 写在前面的话,网上能够找到一些关于ossec方面的资料,虽然很少,但是总比没有强,不过在实际的使用过程中还是会碰到许多稀奇古怪的问题.整理整理我的使用过程,就当做一篇笔记吧 ...

  3. Dubbo架构学习整理

    一. Dubbo诞生背景 随着互联网的发展和网站规模的扩大,系统架构也从单点的垂直结构往分布式服务架构演进,如下图所示: 单一应用架构:一个应用部署所有功能,此时简化CRUD的ORM框架是关键 垂直应 ...

  4. .Net和C#介绍

    一.前言 本文主要针对刚入门以及还需要对基础进行恶补一下的兄弟进行基础介绍,并尽可能的做到客观,如有错误也虚心接受高手门的纠正. 二..Net平台简介 .net即DotNet,首先我先给出微软的定义: ...

  5. Perl文件句柄相关常量变量

    文件句柄相关变量 对应的官方手册:http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles 默认情况下: $/:输入行 ...

  6. python等值和大小比较

    等值.大小比较 在python中,只要两个对象的类型相同,且它们是内置类型(字典除外),那么这两个对象就能进行比较.关键词:内置类型.同类型.所以,两个对象如果类型不同,就没法比较,比如数值类型的数值 ...

  7. MySQL行转列

    IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则 ...

  8. Docker在Linux上运行NetCore系列(二)把本地编译好的镜像发布到线上阿里云仓库

    转发请注明此文章作者与路径,请尊重原著,违者必究. 系列文章:https://www.cnblogs.com/alunchen/p/10121379.html 开始 本篇文章结束在本地创建完成镜像后, ...

  9. 如何定义一个有效的OWIN Startup Class

    命名约定 Katana在程序集内的程序集名称空间下查找一个叫做Startup的类, 通过属性指定 [assembly: OwinStartup(typeof(OwinConsoleApp.Startu ...

  10. element UI Cascader 级联选择器 编辑 修改 数组 路径 问题(转载)

    来源:https://segmentfault.com/a/1190000014827485 element UI的Cascader级联选择器编辑时 vue.js element-ui 2 eleme ...