一、case class

用case修饰的Class 我们称之为Case Class。编译器看到这个case修饰的class,会为这个class加一些额外的特性:

1、编译器会为Case Class增加一个以类名为名字的工厂方法,这个工厂方法作用是构建这个类的对象

val v = Var("x") //构建对象的时候不需要用new关键词

2、编译器默认的为case class的值参数加上了val来进行修饰,所以这些值参数和一个类里的域一样

v.name

3、编译器自动为case class添加了toString、hashCode以及equals方法。可以用 == 来比较case class,比较case class的类型以及case class中的值参数

op.right == Var("x")

4、编译器为case class增加了一个copy方法,使得case class的值参数的值可以修改。如果一个case class中只要几个特定的值参数需要改变的话,用copy比较方便。

val opNew = op.copy(operator = "-")

case 除了可以修饰class,还可以修饰object,就是表示一个单例对象

case class最大的优点就是配合模式匹配

二、Scala的match表达式 和java switch区别

1、Scala的match表达式可以计算出一个值,而Java的switch却不能

2、模式匹配的表达式永远不会穿透到下一个case表达式中, java的switch中没有break的话,则会穿透到下一个分支

3、模式匹配中如果没有任何的模式被匹配到,则抛出MatchError异常

三、SealedClass

当你在用模式匹配的时候,你肯定需要考虑所有场景的case,有的时候我们可以用default来代替所有没有考虑到的情况,但是有的时候这个默认值没有意义,这个时候怎么来保证你能考虑到所有的情况呢?我们让编译器来帮我们考虑,我们可以在case class的父类上加一个sealed的关键字,这个sealed会帮我们做两件事情:

1:在我们定义模式匹配的时候,如果没有考虑全场景,编译器会报警告

2:被sealed修饰的类,不能被在其他文件中的case class继承

四、模式的种类

1、通配符模式  case _        可以用于匹配默认的场景,可以用于可以忽略的对象的域的情况

2、常量模式

def describe(x: Any) = x match {

case 5 => "five"

case true => "truth"

case "hello" => "hi!"

case Nil => "the empty list"

case _ => "something else"

}

describe(5) //res6: String = five

describe(true) //res7: String = truth

describe("hello") //res8: String = hi!

describe(Nil) //res9: String = the empty list

describe(List(1, 2, 3)) //res10: String = something else

3、变量模式

可以将被匹配的表达式的值绑定到模式中的变量中,这样可以在expressions中使用这个变量

val i = 1 + 1

var result = i match {

case 0 => "zero"

case somethingElse => "not zero: " + somethingElse

}

println(result) // not zero: 2

编译器怎么判断是常量模式还是变量模式?

val pi = math.Pi

result = E match {

case pi => "strange math? Pi = " + pi //以小写字母开头的单词被编译器认为是变量模式

}

result = E match {

case `pi` => "strange math? Pi = " + pi //以反引号扩起来的为常量模式

case _ => "OK"

}

4、构造器模式。支持深度匹配

5、序列模式。支持固定长度的序列或者数组,也支持非固定长度。

v match {

case List(0, _*) => println("list it")//匹配含有任意个元素的List,并且第一个元素等于0

case Array(0, _*) => println("array it")//匹配含有任意个元素的Array,并且第一个元素等于0

case _ =>

}

6、元组模式

def tupleDemo(expr: Any) = expr match {

case (a, b, c) => println("matched " + a + b + c)

case _ =>

}

7、类型模式

def generalSizeWithPattern(x: Any) = x match {

case s: String => s.length

case m: Map[Int, Int] => m.size

case _ => -1

}

关于类型擦除,数组是个例外,因为数组在java中是特殊处理了,在scala中也是特殊处理了,在jvm中对应着不同类型的数组,比如int[], float[]等

isIntIntMap(Map(1 -> 1)) //true

isIntIntMap(Map("abc" -> "abc")) //true

isStringArray(Array("abc")) //yes

isStringArray(Array(1, 2, 3)) //no

8、变量绑定

val expr = UnOp("abs", UnOp("abs", Var("x")))

expr match {

case UnOp("abs", e@UnOp("abs", i@Var(_))) => println(e + " " + i)

case _ =>

}

五、模式守卫

在模式中可以定义条件。

def simplifyAdd(e: Expr) = e match {

case BinOp("+", a, b) if a == b => BinOp("*", b, Number(2))

case _ => e

}

六、模式重叠

    尽量避免模式重叠

def simplifyBad(expr: Expr): Expr = expr match {

case UnOp("-", UnOp("-", e)) => e   //第一个case

case UnOp(op, e) => UnOp(op, simplifyBad(e))  //第二个case

}

当case1属于case2的子集,那么case1可以放在case2之前,若放在case2之后,则永远无法执行,编译器会报警告unreachable code.

七、Option

Option视作一个容器,可以有东西,也可以没有东西。Some 表示有且仅有一个东西 None表示没有东西

val opt = Some("aaa")

opt.getOrElse("default")

在模式匹配中使用:

val capitals =

Map("France" -> "Paris", "Japan" -> "Tokyo")

def show(x: Option[String]) = x match {

case Some(s) => s

case None => "?"

}

show(capitals get "Japan") //res25: String = Tokyo

show(capitals get "France") //res26: String = Paris

show(capitals get "North Pole") //res27: String = ?

八、模式在变量定义中的使用

val myTuple = (123, "abc")

val (number, string) = myTuple

val exp = new BinOp("*", Number(5), Number(1))

val BinOp(op, left, right) = exp

九、模式在偏函数中使用

1、一个case序列作为全函数(complete function)

val withDefault: Option[Int] => Int = {

case Some(x) => x

case None => 0

}

2、如果缺少了一个case会出现什么情况呢?编译会出现警告

val second: Option[Int] => Int = {

case Some(x) => x

}

3、如果我们的case列表是部分的场景,我们需要告诉编译器这是一个偏函数(partial function)

val partial : PartialFunction[Option[Int], Int] = {

case Some(x) => x

}

4、我们尽可能的用全函数,因为偏函数如果没有考虑清楚需要处理的case的话,可能会抛异常。

上面的partial就是和下面的p是一个意思

val p =  new PartialFunction[Option[Int], Int] {

override def isDefinedAt(x: Option[Int]) = x match {

case Some(_) => true

case None => false

}

override def apply(v1: Option[Int]) = v1 match {

case Some(x) => x

}

5、如果要使用偏函数,推荐用下面模式

if (partial.isDefinedAt(None)) {

partial(None) //如果单独运行的话,还是会抛异常

}

十、模式在for中使用

val results = List(Some("apple"), None, Some("orange"))

for (Some(fruit) <- results) println(fruit)

val capitals =

Map("France" -> "Paris", "Japan" -> "Tokyo")

for ((country, city) <- capitals)

println("The capital of " + country + " is " + city)

十一、萃取器unapply

含有成员方法unapply的object,我们称之为extractors(萃取器)。extractors可以同时定义apply(可选的)和unapply方法。

转载于:https://blog.51cto.com/13921538/2299797

5、Scala模式匹配相关推荐

  1. Scala模式匹配的亮点——Martin Odersky访谈(四)

    Martin Odersky向Bill Venners和Frank Sommers谈论Scala模式匹配的机制和目的. \\ Scala是一种新兴的通用用途.类型安全的Java平台语言,结合了面向对象 ...

  2. Scala模式匹配和类型系统

    Scala模式匹配和类型系统 1.模式匹配比java中的switch case强大很多,除了值,类型,集合等进行匹配,最常见的Case class进行匹配,Master.scala有大量的模式匹配. ...

  3. Scala模式匹配--样例类--密封样例类--偏函数

    Scala模式匹配--样例类--密封样例类--偏函数 模式匹配 等价于java的switch caseval c = '+'c match{case '+' => println(111)cas ...

  4. scala 模式匹配 match

    文章目录 一.match 基本介绍 二.match 的细节和注意事项 三.模式匹配之条件守卫 四.模式匹配之变量匹配.常量匹配 五.模式匹配之类型匹配 六.模式匹配之数组匹配 七.模式匹配之集合匹配 ...

  5. scala 模式匹配

    Scala 中的模式匹配类似于 Java 中的 switch 语法 1 基本语法 模式匹配语法中,采用 match 关键字声明,每个分支采用 case 关键字进行声明,当需 要匹配时,会从第一个 ca ...

  6. Scala模式匹配详解

    前言 Scala 中的模式匹配类似于 Java 中的 switch 语法 Java中的switch语法,default就是都不符合 int i = 10 switch (i) {case 10 :Sy ...

  7. Scala模式匹配,case 字符串,case 匹配类型,case 匹配数组,case 匹配List,case 匹配元组,case匹配case class和case object

    一. 模式匹配和样例类 Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等. 并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配 1. 匹配字 ...

  8. scala 模式匹配详解 1

    什么是模式? 一些刚从java转到scala的同学在开发的过程中犹如深陷沼泽,因为很多的概念或风格不确定,scala里有很多的坑,模式匹配也算一个.我整理了一下自己所理解的概念,以及一些例子.这个系列 ...

  9. scala 模式匹配概念及用法示例

    概念 可以理解为升级版的java switch 1 java中的switch -case是一个分支结构,用于匹配整型(byte,short,int,char),字符串,枚举. (long类型不可以) ...

最新文章

  1. python凯撒密码详解_Python基础题目集--课堂案例
  2. JAVA基础3-选择语句
  3. java-二分查找树的实现
  4. Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数)...
  5. 2000年考研英语阅读理解文章三
  6. python怎么执行csv文件_无法读取/打开/或对CSV文件python 3.4windows执行任何操作
  7. 6.第一个程序Hello World
  8. python解acm题_python ACM ,持续更新中。。。。。。。。。。。。
  9. mysql router 多台写入_Centos7部署MySQL-router实现读写分离及从库负载均衡
  10. python3数据结构菜鸟教程_Python3
  11. 快速对表的某字段赋递增的数值
  12. PGIS 天地图主题颜色背景修改 图片 filter 蓝色 HTML CSS IMG filter 颜色矩阵在线计算 RGBA转换 SVG  feColorMatrix
  13. 新晋院士!顶尖985,迎来新校长!
  14. java输入输出流实例代码
  15. 环境试验之单臂跌落试验机操作规程
  16. 在vscode中php语言配置,vscode配置go语言开发环境
  17. 2022虎符线上团队赛 有关web的部分题解(持续更新)
  18. NW.js之基础篇(2)
  19. 如何安装Eclipse WTP插件
  20. 湖北专升本MySQL复习(MySQL数据库实用教程)——MySQL数据表的操作

热门文章

  1. 大跌眼镜!杭州一程序员年薪 30 万,竟靠偷车厘子缓解压力?
  2. 程序员如何乘风破浪?从数据库历史看技术人发展 | CSDN 高校俱乐部
  3. 浏览器访问网页过程中发生了什么?(转)
  4. 『原创』+『参考』基于PPC的图像对比程序——使用直方图度量
  5. Hotel California
  6. 2011年 软件所信息安全国家重点实验室复试回忆
  7. MyBatis学习总结(9)——使用MyBatis Generator自动创建代码
  8. TCP三次握手,四次分手
  9. pytorch读取文本训练
  10. PowerDesigner打开设计文件后提示failed to read the fileXXX的解决办法