scala case class
在我们详细介绍Scala的Case class和模式匹配之前,我们可以通过一个简单的例子来说明一些基本概念。我们设计一个函数库,这个函数库可以用来计算算术表达式,为简单起见,我们设计的算术表达式只侧重于变量,数字,单操作符,和双操作符。我们可以采用如下的Scala类定义:
abstract class Expr
case class Var(name:String) extends Expr
case class Number(num:Double) extends Expr
case class UnOp(operator:String, arg:Expr) extends Expr
case class BinOp(operator:String,left:Expr,right:Expr) extends Expr
这里我们定义了一个抽象类Expr和四个子类(分别代表变量,数值,单操作符,双操作符),Scala允许我们不定义类的实现,实际我们是class C 和 class C {}是等价的。
case classes
我们可以看到上面的四个子类定义前面我们使用了case关键字,使用了case关键字的类定义就是case classes。使用这个关键字,Scala编译器会自动为你定义的类生成一些成员。
首先,编译器为case class生成一个同名的对象构造器(Factory Method),也就是你可以使用 Var(“x”) 来创建一个类的实例,而无需使用new Var(“x”).
scala> val x = Var("x")
x: Var = Var(x)
这个构造器在嵌套使用时显得非常简洁明了,比如 我们构建如下的表达式,这种写法避免了很多new 的使用。
scala> val op=BinOp("+",Number(1),x)
op: BinOp = BinOp(+,Number(1.0),Var(x))
其次,Scala编译器为case class的构造函数的参数创建以参数名为名称的属性,比如Val的类的参数name:String 可以直接通过 .name访问,比如:
scala> x.name
res1: String = x
第三,编译器为case class 构造了更自然的toString,hashCode和equals实现,它们会递归打印,比较case class的参数属性。比如:
scala> println(op)
BinOp(+,Number(1.0),Var(x)) scala> op.right == Var("x")
res3: Boolean = true
最后一点,Scala编译器为case class添加了一个Copy方法,这个copy方法可以用来构造类对象的一个可以修改的拷贝。这对于使用已有的对象构造一个新实例非常方便,你只要修新创建实例的某些参数即可。
比如我们想创建一个和op类似的新的实例,只想修改+为-,可以使用:
scala> op.copy(operator="-")
res4: BinOp = BinOp(-,Number(1.0),Var(x))
以上这些惯例带来了很多便利,这些便利也需要一些小小的代价,就是需要在class前面使用case关键字,而构造后的类由于自动添加了一些方法而变大了些。case class带来的最大的好处是它们支持模式识别。
Pattern matching
比如说你需要简化表达式的表示方法,这里给出一个简单的规则:
UnOp(“-”,Unop(“-”,e)) => e//负负得正
BinOp(“+”,e,Number(0)) => e//和0加
BinOp(”*”,e,Number(1)) => e //和1乘
使用模式匹配,在Scala我们几乎和使用和上面规则非常类似的代码来实现表达式的简化:
scala> def simplifyTop(expr :Expr) :Expr = expr match {
| case UnOp("-",UnOp("-",e))=>e
| case BinOp("+",e,Number(0))=>e
| case BinOp("*",e,Number(1))=>e
| case _ => expr
|
| }
simplifyTop: (expr: Expr)Expr
scala> simplifyTop(UnOp("-",UnOp("-",Var("x"))))
res6: Expr = Var(x)
scala>
simplifyTop 定义使用了match表达式,它对应Java的switch语句,但它的语法和switch不同,它的selector 在match前面:
selector match { alternatives}
一个模式匹配由多个可选项组成,没个选项由case开始,每个选项定义一个模式,每个模式对应一个表达式,表达式应用到当模式匹配的时候。模式和表达式之间使用=>分隔。
一个match表达式的结果取决于第一个匹配的可选项,当该项模式匹配时,该模式=>后的表达式被选中然后计算该表达式的值。
一个常量模式,比如本例中的“+”和“0”, 匹配对应的常数,一个变量模式比如e,可以匹配任意的值。然后=>右边的表示式可以应用这个变量,“_”为通配符,可以匹配任意的值。
构造器模式,比如UnOp(“-”,e),可以匹配UnOp类型的值,这个UnOp的第一个参数为”-“,第二个参数可以为任意。
和Java的 switch语句比较,Scala的match 有以下几个不同点:
- match为一表达式,有返回结果,其返回结果为匹配项表示式的值。
- match的选项没有break,也不会自动匹配下一个选项(no fall through).
- 如果没有一个选项匹配,那么将抛出MatchError异常,这意味着你必须保证考虑到Match的所有的选项,因此可能你需要添加一个缺省选项。
scala case class的更多相关文章
- learning scala Case Classses
package com.aura.scala.day01 object caseClasses { def main(args: Array[String]): Unit = { // 注意在实例化案 ...
- scala case类
case类 case class Person(name:String) case 类有如下特点: 1. 构造参数默认是 val 的. 2. case 类实例化对象的时候,不需要 new 关键字.因为 ...
- scala 学习: case class
case class: 1.定义为case class 的类在实例化时,可以不使用new 关键字. case class People(name:String, age:Int) val zhangs ...
- Scala class和case class的区别
在Scala中存在case class,它其实就是一个普通的class.但是它又和普通的class略有区别,如下: 1.初始化的时候可以不用new,当然你也可以加上,普通类一定需要加new: scal ...
- Scala化规则引擎
1. 引言 什么是规则引擎 一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑.业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技 ...
- Beginning Scala study note(5) Pattern Matching
The basic functional cornerstones of Scala: immutable data types, passing of functions as parameters ...
- Beginning Scala study note(3) Object Orientation in Scala
1. The three principles of OOP are encapsulation(封装性), inheritance(继承性) and polymorphism(多态性). examp ...
- 深入了解 Scala 并发性
2003 年,Herb Sutter 在他的文章 “The Free Lunch Is Over” 中揭露了行业中最不可告人的一个小秘密,他明确论证了处理器在速度上的发展已经走到了尽头,并且将由全新的 ...
- 2-Spark高级数据分析-第二章 用Scala和Spark进行数据分析
数据清洗时数据科学项目的第一步,往往也是最重要的一步. 本章主要做数据统计(总数.最大值.最小值.平均值.标准偏差)和判断记录匹配程度. Spark编程模型 编写Spark程序通常包括一系列相关步骤: ...
随机推荐
- Sql Server 基础知识
Sql Server 基础知识: http://blog.csdn.net/t6786780/article/details/4525652 Sql Server 语句大全: http://www.c ...
- poj 3895(求无向图的最大简单环)
题目链接:http://poj.org/problem?id=3895 思想很简单,就是dfs,并且用一个数组记录到该节点所走过的长度,然后如果遇到已经走过的,就说明存在环了, 更新一下ans. /* ...
- Spring中属性文件properties的读取与使用
实际项目中,通常将一些可配置的定制信息放到属性文件中(如数据库连接信息,邮件发送配置信息等),便于统一配置管理.例中将需配置的属性信息放在属性文件/WEB-INF/configInfo.propert ...
- POJ 1182 食物链 (经典带权并查集)
第三次复习了,最经典的并查集 题意:动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们 ...
- JMeter处理jdbc请求后的响应结果
JMeter如果进行JDBC请求,请求后的响应结果如何给下一个请求用(也就是传说中的关联),于是研究了一下,下面将学习的成果做个记录: 1.添加 "JDBC Connection Confi ...
- JMeter性能监测插件介绍(三)
JMeter 性能监测插件介绍 压力测试过程中,能够随时对负载服务器的健康状况的把控是相当重要的,有了这些数据,我们才能准确分析出服务器负载瓶颈.JMeter 插件包现在能够支持服务器监控,可以在所有 ...
- 在CSDN中添加友情连接
<a bref='http://www......'>友情连接</a><br/> <a bref='http://www......'>友情连接2< ...
- 04 DOM一窥
BOM 浏览器对象模型 * window alert(); 弹出框 confirm() 询问框 setInterval("run()",1000); 每隔1秒执行run ...
- Thymeleaf 常用属性
Thymeleaf 常用属性 如需了解thymeleafThymeleaf 基本表达式,请参考<Thymeleaf 基本表达式>一文 th:action 定义后台控制器路径,类似<f ...
- iOS开发实用干货——强化你的Xcode控制台
f(x) 郑秀晶程序员不要整天看代码,偶尔也要看看风景?? www.90168.org先上一张我的Xcode控制台的图片让你们感受一下 酷炫控制台 是不是觉得很酷?不过仅仅是酷还是远远不够的,当你点击 ...