前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有趣的Scala模式匹配

有趣的Scala模式匹配

作者头像
哒呵呵
发布2018-08-06 14:17:02
1K0
发布2018-08-06 14:17:02
举报
文章被收录于专栏:鸿的学习笔记鸿的学习笔记

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

选择语句 match {可选分支}

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

代码语言:javascript
复制
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的模式匹配是按顺序的)。类似于通配符,为了使用传入的变量,还可以指定变量(当以小写字母开头时,会被认为时变量,然后会被认为是常量),使用变量模式。

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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采用了深度匹配,这说明模式匹配不仅仅会检查类是否相等,还会检查对象的内容是否匹配。由构造方法匹配自然而然就可以引申为序列模式匹配和元组匹配。 序列模式匹配

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档