有趣的Scala模式匹配

Scala提供了一种类比switch/case更为强大的选择匹配模式,写作

选择语句 match {可选分支}

它被称为模式匹配,模式匹配包含了一系列以case关键字开头的分支,每一个分支包含一个模式或者是多个表达式。模式有很多种,例如常量模式('*',1),变量模式(可以匹配任何值),通配模式(又见面了,'_'符号),构造方法模式(类似于样例类的初始化)等等。 用一个例子简单说明就是:

scala> def matchTest(expr:Int) = expr match {
     |     case 1 => println(1)
     |     case 2 => println(2)
     |     case _ => println(3)
     |   }
matchTest: (expr: Int)Unit

scala> matchTest(1)
1

scala> matchTest(2)
2

scala> matchTest(4)
3

match表达式会逐个尝试case里的模式直到匹配为止,如果没有匹配上就会抛出异常MatchError,所以一定要确保case都被覆盖。上例所展示的就是常量模式的常量1,2去匹配,还使用了_通配符匹配任何对象(建议放在最后面,因为Scala的模式匹配是按顺序的)。类似于通配符,为了使用传入的变量,还可以指定变量(当以小写字母开头时,会被认为时变量,然后会被认为是常量),使用变量模式。

scala>  def matchTest(expr:Int) = expr match {
     |     case 0 => println(0)
     |     case some => println(some)
     |   }
matchTest: (expr: Int)Unit

scala> matchTest(0)
0

scala> matchTest(3)
3

当然,除了上述的模式,还可以选择构造方法匹配。例如:

scala> case class Test2(a:String)
defined class Test2

scala> case class Test1(name:String, mt:Test2)
defined class Test1

scala> def matchTest(expr:Test1):Test2 = expr match {
     |     case  Test1("a",e)=> e
     |     case _ => Test2("ab")
     |   }
matchTest: (expr: Test1)Test2

scala> val a = Test2("cd")
a: Test2 = Test2(cd)

scala> val b = Test1("ab",a)
b: Test1 = Test1(ab,Test2(cd))

scala> matchTest(b)
res0: Test2 = Test2(ab)

scala> val b = Test1("a",a)
b: Test1 = Test1(a,Test2(cd))

scala> matchTest(b)
res1: Test2 = Test2(cd)

我们创造了两个样例类Test1和Test2,Test1接受Test2作为构造参数,实例化两个样例类后发现,在构造方法匹配中,Scala采用了深度匹配,这说明模式匹配不仅仅会检查类是否相等,还会检查对象的内容是否匹配。由构造方法匹配自然而然就可以引申为序列模式匹配和元组匹配。 序列模式匹配

scala> def matchTest(expr:List[String]):Unit = expr match {
     |     case  List("a",_,_)=> println("right")
     |     case _ => println("wrong")
     |   }
matchTest: (expr: List[String])Unit

scala> matchTest(List("a"))
wrong

scala> matchTest(List("a","b","c"))
right

可以使用_*来省略后面的多个_符号 元组模式

scala>   def matchTest(expr:Any):Unit = expr match {
     |     case  (a,b,c)=> println("found:" +a+b+c)
     |     case _ => println("wrong")
     |   }
matchTest: (expr: Any)Unit

scala> matchTest(("a","b","c"))
found:abc

匹配类型的模式 除了上述的匹配模式选出值,还可以用来做类型检查和测试。这里可以根据传进去的值的类型反馈对应的结果。

scala>   def matchTest(expr:Any) = expr match {
     |     case s:String=> s.length
     |     case i:Int => i
     |   }
matchTest: (expr: Any)Int

scala> matchTest("abc")
res5: Int = 3

scala> matchTest(2)
res6: Int = 2

本文分享自微信公众号 - 鸿的学习笔记(shujuxuexizhilu)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-04-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯NEXT学位

今天我就说三句话

11220
来自专栏钱塘大数据

中国互联网协会发布:《2018中国互联网发展报告》

在2018中国互联网大会闭幕论坛上,中国互联网协会正式发布《中国互联网发展报告2018》(以下简称《报告》)。《中国互联网发展报告》是由中国互联网协会与中国互联...

13150
来自专栏腾讯大讲堂的专栏

白底黑字or黑底白字,眼睛更喜欢哪一个?

11910
来自专栏FSociety

SQL中GROUP BY用法示例

GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类...

5.1K20
来自专栏前端桃园

知识体系解决迷茫的你

最近在星球里群里都有小伙伴说道自己对未来的路比较迷茫,一旦闲下来就不知道自己改干啥,今天我这篇文章就是让你觉得一天给你 25 个小时你都不够用,觉得睡觉都是浪费...

19440
来自专栏微信公众号:小白课代表

不只是软件,在线也可以免费下载百度文库了。

不管是学生,还是职场员工,下载各种文档几乎是不可避免的,各种XXX.docx,XXX.pptx更是家常便饭,人们最常用的就是百度文库,豆丁文库,道客巴巴这些下载...

43230
来自专栏web前端教室

你可以从面试中学到什么?

讲一下我对面试的一些。。。“偏见”,哈哈,熟悉我的同学们一定要批判的读接下来的内容哈。

11600
来自专栏Ken的杂谈

【系统设置】CentOS 修改机器名

17230
来自专栏haifeiWu与他朋友们的专栏

复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负...

26340
来自专栏钱塘大数据

理工男图解零维到十维空间,烧脑已过度,受不了啦!

让我们从一个点开始,和我们几何意义上的点一样,它没有大小、没有维度。它只是被想象出来的、作为标志一个位置的点。它什么也没有,空间、时间通通不存在,这就是零维度。

26530

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励