前面两节我们已经多次接触过case关键字了。case关键字不仅可以用在match/case中来执行模式匹配,也可以用来修饰类。不过用case修饰的类也主要是用来做模式匹配。在上一节曾经提到过match可以是Any类型的所有类,为什么还需要使用case关键字来修饰呢?假定有这样一个场景:我们要接收和处理股票交易信息,买卖消息通常会带有一些信息,诸如股票名称、数量。把这些信息存到对象里会很方便,但是如何对他们进行模式匹配呢?这时我们就会用到case类了。case类是模式匹配器(pattern matcher)可以识别和匹配的类。

下面是一个例子:

abstract class Trade()

case class Sell(stockSymbol: String, quantity: Int) extends Trade

case class Buy(stockSymbol: String, quantity: Int) extends Trade

case class Hedge(stockSymbol: String, quantity: Int) extends Trade

class TradeProcessor {
def processTransaction(request: Trade) {
request match {
case Sell(stock, 1000) => println("Selling 1000-units of " + stock)
case Sell(stock, quantity) => printf("Selling %d units of %s\n", quantity, stock)
case Buy(stock, quantity) if (quantity > 2000) => printf("Buying %d (large) units of %s\n", quantity, stock)
case Buy(stock, quantity) => printf("Buying %d units of %s\n", quantity, stock)
}
}
}

这里,用request匹配Sell和Buy。如果接收到的股票代码和数量得到匹配,就会分别存储到模式变量stock和quantity里。这里还用到特定常量值(比如quantity为1000)或是卫述句(比如检查if quantity > 2000)进行匹配。

此时我们已经为Trade类准备了三个实现,我们并不需要其它的实现,更不希望其他人再实现这个trait。此时,我们可以使用sealed关键字来限制只能在当前文件下实现这个trait。就像这样:

sealed abstract class Trade()

case class Sell(stockSymbol: String, quantity: Int) extends Trade

case class Buy(stockSymbol: String, quantity: Int) extends Trade

case class Hedge(stockSymbol: String, quantity: Int) extends Trade

在上面的代码中,Trade的所有实现case类都有参数。当一个case类没有参数时,记得在使用的时候一定要加上括号,不然传递的不再是这个类的实例,而是它的伴生对象。这个伴生对象混入了scala.Function0 trait,这意味着它可以当作函数用。所以,最终传入的是一个函数,而不是case类的实例。

#################

scala学习手记40 - 使用case类的更多相关文章

  1. scala学习手记40 - case表达式里的模式变量和常量

    再来看一下之前的一段代码: def process(input: Any) { input match { case (a: Int, b: Int) => println("Proc ...

  2. scala学习手记17 - 容器和类型推断

    关于scala的类型推断前面已经提到过多次.再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var ...

  3. Scala学习笔记(三)类层级和特质

    无参方法 功能:将方法的定义转换为属性字段的定义: 作用范围:方法中没有参数,并且方法仅能通过读取所包含的对象属性去访问可变状态,而不改变可变状态,就可使用无参方法: 例子: abstract cla ...

  4. scala学习手记29 - 偏应用函数

    调用函数可以说成是将函数应用于实参.如果传入所有的预期的参数,就完全应用了这个函数.如果只传入几个参数,就会得到一个偏应用函数. 偏应用函数是一个特殊的概念,在scala中它是使用val定义的,但是在 ...

  5. scala学习手记15 - 独立对象和伴生对象

    上一节中的单例对象MarkerFactory 就是一个独立对象的例子.尽管它管理着Marker类,但是它并没有关联到任何类上. scala也可以创建关联到类上的对象.这样的对象同类共享同一个名字,这样 ...

  6. scala学习手记6 - 字符串与多行原始字符串

    scala中的字符串类就是java中的java.lang.String类.不过scala也为String提供了一个富封装类:scala.runtime.RichString. scala可以将java ...

  7. scala学习手记13 - 类继承

    在scala里,类继承有两点限制: 重写方法需要使用override关键字: 只有主构造函数才能往父类构造函数中传参数. 在java1.5中引入了override注解,但不强制使用.不过在scala中 ...

  8. scala学习手记11 - 类定义

    这里会通过与Java比较的方式来说明scala是如何创建类的. 先来看一下Java中是如何定义一个类的: public class Car { private final int year; priv ...

  9. scala学习手记4 - Java基本类型对应的scala类

    在Java中变量类型分为两大类:基本类型和引用类型.虽然在JDK1.5以后引入了自动装箱和自动拆箱机制,大大减少了我们在直接类型和引用类型之间的纠结,但仍有一些我们不得不考虑的问题.比如我在工作遇到的 ...

随机推荐

  1. SQL架构信息读取

    --架构: select * from information_schema.SCHEMATA --表: select table_name from information_schema.table ...

  2. Python菜鸟之路:Django 路由补充1:FBV和CBV - 补充2:url默认参数

    一.FBV和CBV 在Python菜鸟之路:Django 路由.模板.Model(ORM)一节中,已经介绍了几种路由的写法及对应关系,那种写法可以称之为FBV: function base view ...

  3. img标签使用onload进行src更改时出现的内存溢出问题

    最近在开发时需要在img标签加载完成后修改src属性,使用了onload方法. 但是在方法体中最后没有把onload事件指向null, 导致了循环调用onload方法,CPU占用一直居高不下,最后只要 ...

  4. JavaScript 入门之常见对象

    常见对象 1. Object 对象 2. String 对象 3. Array 对象 4. Date 对象 5. Number 对象 6. 自定义对象 with 语句 为了简化对象调用内容的书写 格式 ...

  5. Selenium定位不到指定元素原因之iframe(unable to locate element)

    浏览过程中,图片中的内容可能太小,无法看清,可以>右键>在新标签中打开 Outline 项目原因,需要用selenium实现模拟登陆.模拟上传文件,自然就需要模拟点击[上传]按钮: 模拟点 ...

  6. JsonResponse对象浅析

    JsonResponse   JsonResponse 对象: class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_ ...

  7. Swift学习笔记四:数组和字典

      Swift 提供两种集合类型来存储集合,数组和字典. 数组是一个同类型的序列化列表集合.字典是一个能够使用相似于键的唯一标识符来获取值的非序列化集合.也就是说数组是有序的.字典是无序的. 一. 数 ...

  8. Ubuntu 16.04 安装 JDK 及 Eclipse 详细步骤(转发:https://blog.csdn.net/bluish_white/article/details/56509446)

    2017.3.1更新 修正了一些命令,现在按照文章步骤配置不会出现问题了. JDK 安装及配置 参考来源:http://www.linuxidc.com/Linux/2017-02/140908.ht ...

  9. 系统间接口联调总是报500 for URL 和 乱码

    两个系统做数据传输时,懒省事,直接访问 action 方式.结果总是报500,或者fileNotFount. 究其原因是因为两边的数据格式没对应上.post请求返回的格式是String,数据提供方返回 ...

  10. exports与module.exports的区别

    nodejs有自己的模块系统,分为文件模块和内置模块.webpack是运行在node环境中,在学习vue-cli的webpack配置的时候, 发现有的文件模块: exports.fun1=functi ...