Scala中提供了比java,c更加强大的switch语句——match,而且不用担心因为忘记写break语句而发生case穿透
1.更好的switch
与if,类似match也是表达式,如下一个用于匹配字符的函数

def charMatch(c: Char) = c match {case '+' => 1case '-' => -1case _ => 0}

你可以使用任何类型,而不仅仅是数字匹配

def colorMatch(c:Color) = c match {case Color.RED => 0xff0000case Color.BLACK => 0x000000case Color.YELLOW => 0xffff00case _ => 0}

2.守卫
我们修改一下例一,可以添加if这样的守卫,来匹配所有数字,守卫可以是任何Boolean条件

def charMatch(c: Char) = c match {case '+' => 1case '-' => -1case ch if Character.isDigit(ch) => Character.digit(ch, 10)case _ => 0}

3.模式中的变量
如果case后跟着一个变量名,那么匹配的表达式会被复制给那个变量,你可以将case _
看做这个特性的一个特殊情况,变量名为_可以通配。

case **ch** if Character.isDigit(**ch**) => Character.digit(**ch**, 10)

变量模式和常量模式如果有冲突,可以用反引号“

import math._def dMatch(d: String) = d match {case `Pi` => 3.14case n => Integer.parseInt(n)case _ => 0}

4.类型匹配
这样就不用使用isInstanceOf的操作符判断类型,在用asInstanceOf转换
但是要注意Map和其他有泛型的集合,模式匹配发生在运行期,泛型会被擦掉
Map[Int,Int] 要用Map[_ , _]代替

def anyMatch(obj: Any) = obj match {case i: Int => icase s: String => Integer.parseInt(s)case _: BigInt => Int.MaxValuecase m: Map[_, _] => 1 //       模式匹配发生在运行期  case _ => 0}

5.匹配数组列表和元组

//  匹配数组,列表和元组def arrMatch(a: Array[Int]) = a match {case Array(0) => "0"case Array(x, y) => x + " " + ycase Array(0, _*) => "0 ..."case _ => "something else"}
//  case class ::[E] (head :E,tail:List[E]) extends List[E]def listMatch(l: List[Int]) = l match {case 0 :: Nil => "0"
//          多个中置表达式更易读case x :: y :: Nil => x + " " + ycase h :: t => h + " " + t.mkString(" ")
//      上面的一种写法,将调用::.unapply(lst)case ::(h,t) => hcase 0 :: tail => "0 ..."case _ => "something else"}def pairMatch(p: (Int, Int)) = p match {case (0, _) => "0 ..."case (y, 0) => y + " 0"case _ => "neither is 0"}

6.提取器extractor
提取unapply或unapplySeq方法,已经在别的文章的介绍过了
这里来注意一下了一个正则表达式的场景,正则中的分组匹配,可以用提取器来获取每个分组

//  提取器extractorval pattern = "([0-9]+) ([a-z]+)".rdef patternMatch(s: String) = s match {//      这里的提取器不是伴生对象而是提取器对象case pattern(num, item) => numcase _ => 0}

7.变量声明中的模式

    val (x,y) = (1,2)
//  /%获取商和余数val (q,r) = BigInt(10) /% 3val arr = Array(1,2,3)
//  提取数组中的第一第二个元素val Array(f,s,_*) = arr 

8.for表达式中的模式

import collection.JavaConversions._
//  for((k,v) <- System.getProperties) println(k -> v)
//  匹配为空的值for((k,v) <- System.getProperties if v == "") println(k -> v)for((k,"") <- System.getProperties) println(k -> "")

9.样例类
这是一种经过优化而被用于模式匹配的类

    abstract class Amountcase class Dollar(value:Double) extends Amountcase class Currency(value:Double,unit:String) extends Amountcase object Nothing extends Amount //单例对象不用加括号//  样例类的实例使用(),样例对象不用使用()def amountMatch(a:Amount) = a match{case Dollar(v) => "$" + v
//      case Currency(_,u) => "Oh noes , I got "+u
//      如果两个参数是对偶,则可以写成中置表示法case a Currency u => a+" Oh noes , I got "+ucase Nothing => ""}

10.copy方法和带名参数
通过带名参数直接修改这些对象的属性

//  copy方法和带名参数val amt = Currency(29.95,"EUR")val price = amt.copy()val price1 = amt.copy(value = 20.0)val price2 = amt.copy(unit = "CHF")

11.case 中置表示法

//  中置表示法case object +:{def unapply[T](input:List[T]) = if(input.isEmpty) None else Some((input.head,input.tail))}1 +: 7 +: 9 +: Nil match {//可以用+:来析构列表case f +: s +: r => f+s+r.lengthcase _ => None}

12.匹配嵌套结构
场景售卖某个商品,会将商品捆绑销售:

    abstract class Itemcase class Article(description:String,price:Double) extends Itemcase class Bundle(description:String,price:Double,items:Item*) extends ItemBundle("Book1",20,Article("Book2",39),Bundle("Book3",25,Article("Book4",31),Article("Book5",11)))def matchItem(i:Item) = i match{
//  匹配到了被绑定到Bundle第一个Article的描述desccase Bundle(_,_,Article(_,p),_*) => println(p)
//      匹配到Bundle只含有一个Article的第一个Article
//      @可以将变量绑定到嵌套的值上case Bundle(_,_,art @ Article(_,_),rest) => println(art.price)
//      可以匹配到Bundle含有多个Article的第一个Articlecase Bundle(_,_,art @ Article(_,_),rest @ _*) => println(art.price)
//      case _ => println(None)}
//  可以用于计算商品的价格def price(it:Item):Double = it match{
//      计算单本书的价格case Article(_,p) => p
//      递归计算一捆书的价格case Bundle(_,disc,its @ _*) => its.map(price _).sum - disc}

13.密封类sealed
当你用样例类来做匹配是,你可能想让编译器确保你已经列出了所有的可能选择。
要达到这个目的,需要将其超类声明为sealed:

    sealed abstract class Amountcase class Dollar(value:Double) extends Amountcase class Currency(value:Double,unit:String) extends Amountcase object Nothing extends Amount //单例对象不用加括号

密封类何所有子类必须在同一个源文件中定义。如果要加上一个欧元类:

case class Euro(value:Double) extends Amount

他们必须在哪个文件中完成。
14.模拟枚举

//  模拟枚举,样例类可以模拟枚举类,scala不自带枚举sealed abstract class TrafficLightColorcase object Red extends TrafficLightColorcase object Yellow extends TrafficLightColorcase object Green extends TrafficLightColordef trafficLightMatch(light:TrafficLightColor) = light match{case Red  => "stop"case Yellow  => "hurry up"case Green  => "go"}

15.Option类

option可能存在有可能不存在的值。其样例子类Some包装了某个值如:Some(“Fred”),而样例对象None表示没有值

//  Option支持泛型 Some("Fred") => Some[String]
//  Map类的get返回一个Option,用模式匹配来获取值val scores = Map("Bob" -> 75,"Alice" -> 90)scores.get("Alice") match {case Some(s) => println(s)case None => println("no score")}
//  不过这很烦val score = scores.get("Alice")if(score.isEmpty) println("no score") else  println(score.get)
//  这也很烦 使用getOrElseprintln(score.getOrElse("no socre"))

16.偏函数
偏函数必须位于编译器可以推断返回类型的上下文中。当你把它复制个一个PartialFunction[Char,Int]有类型声明的变量,和当做参数传递是符合这个要求。
被包含在{}一组case语句是一个偏函数—不是对所有输入值都有定义的函数。他是partailFunction[A,B]类的一个实例。A是参数类型,B是返回值类型。
该类有两个方法:apply方法从匹配到的模式计算函数值,而isDefinedAt只要有一个匹配返回true。

    val func : PartialFunction[Char,Int] = {case '+' => 1;case '-' => -1}func('-') //调用了f.apply('-'),-1func.isDefinedAt('0')//falsefunc('0')//MacthError
//  collect方法将偏函数作为参数"-3+4".collect(func) //Vector(-1,1)

scala中的match详解相关推荐

  1. js 正则中冒号代表什么_javascript中正则表达式语法详解

    好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉.就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,主要 ...

  2. Python中self用法详解

    Python中self用法详解 https://blog.csdn.net/CLHugh/article/details/75000104 首页 博客 学院 下载 图文课 论坛 APP 问答 商城 V ...

  3. BLAST+中blastn参数详解

    [转]BLAST+中blastn参数详解 2012-05-22 13:25 转载自  lidaof 最终编辑  lidaof 与之前的blast相比,新的blast+将blastn,blastx等合作 ...

  4. ALSA声卡驱动中的DAPM详解之四:在驱动程序中初始化并注册widget和route

    前几篇文章我们从dapm的数据结构入手,了解了代表音频控件的widget,代表连接路径的route以及用于连接两个widget的path.之前都是一些概念的讲解以及对数据结构中各个字段的说明,从本章开 ...

  5. Asp.net中GridView使用详解(引)【转】

    Asp.net中GridView使用详解(引) GridView无代码分页排序 GridView选中,编辑,取消,删除 GridView正反双向排序 GridView和下拉菜单DropDownList ...

  6. Linux中iptraf命令详解(IP局域网监控工具)

    2019独角兽企业重金招聘Python工程师标准>>> Linux中iptraf命令详解(IP局域网监控工具) 发布时间:2017-12-27 20:46:03   作者:佚名    ...

  7. ArcGIS Engine中的Symbols详解

    转自原文 ArcGIS Engine中的Symbols详解 本文由本人翻译ESRI官方帮助文档.尊重劳动成果,转载请注明来源. Symbols ArcObjects用了三种类型的Symbol(符号样式 ...

  8. js路由在php上面使用,React中路由使用详解

    这次给大家带来React中路由使用详解,React中路由使用的注意事项有哪些,下面就是实战案例,一起来看一下. 路由 通过 URL 映射到对应的功能实现,React 的路由使用要先引入 react-r ...

  9. Linux中etc目录详解

    Linux中etc目录详解 /etc目录 包含很多文件.许多网络配置文件也在/etc 中. /etc/rc   or/etc/rc.d   or/etc/rc*.d   启动.或改变运行级时运行的sc ...

最新文章

  1. Nagios的安装和基本配置(一:知识点总结及环境准备)
  2. 编写一个程序,它从标准输入(终端)读取C源代码,并验证所有的花括号都正确的成对出现。...
  3. 迭代法求解线性方程组
  4. ESP8266\ESP32\ESP32-S2芯片支持哪些调试方式呢
  5. android 减少图片出现oom错误
  6. g4e基础篇#6 了解Git历史记录
  7. 不通过ios审核 安装苹果app php,iOS APP审核被拒的解决之道(2.1)
  8. 语言栈十进制转十六进制_十进制数转二进制、八进制、十六进制等任意进制_C语言「抄作业」...
  9. C++面向对象程序设计课程笔记(第三周)
  10. 【POJ2559】Largest Rectangle in a Histogram(单调栈)
  11. mysql 小技巧
  12. linux mount挂载
  13. linux与windows共享(四)
  14. 创业36条军规值得一读
  15. 102分布式电商项目 - JVM调优(理论篇)
  16. c语言实现模糊分类矩阵,模糊聚类分析C程序实现
  17. mysql 表基本操作(创建表、添加主键、外键、非空约束、唯一性约束、默认约束、自动增加)
  18. android定时开关机源码,定时关机程序及源码(易语言)-带设置自动启动功能
  19. python substr_Python字符串的方法
  20. 论文阅读 2017 —— Sensor Fusion for Fiducial Tags: Highly Robust Pose Estimation from Single Frame RGBD

热门文章

  1. swiper跳转指定slides,其他路由跳转swiper指定slides
  2. matlab bar3 颜色,matlab中怎么控制柱状图标注的颜色?
  3. uni-app支付宝小程序map地图组件基础操作+画多边形+打点连线
  4. 华清远见重庆中心学习-受控组件,非受控组件
  5. 如何删除WhatsApp消息
  6. seo是做什么-程绩
  7. 细观Google全面大揭秘
  8. Android——SVG图片转成安卓能用的vector矢量图
  9. 问题 E: 天宝便利店
  10. 学生护眼台灯哪个牌子最好?学生学习专用护眼台灯推荐