scala 模式匹配详解 2 scala里是怎么实现的?
在这篇martin和另外两位模式匹配领域专家的论文里说了模式匹配的几种实现方式,以及scala是选择哪种方式来实现的。
http://lampwww.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf
我引用了里面的一些描述。
在面向对象的程序中数据被组织为一级一级的类(class)
面向对象语言在模式匹配方面的问题在于如何从外部探测这个层级。
有6种实现模式匹配的方法:
1) 面向对象的分解 (decomposition)
2) 访问器模式 (visitor)
3) 类型测试/类型造型 (type-test/type-cast)
4) typecase
5) 样本类 (case class)
6) 抽取器 (extractor)
论文里从3个维度9个标准来对比了各种实现方式:
简明程度(框架支持、浅匹配、深匹配),维护性(表征独立、扩展性),性能(基础性能、广度和深度延展性)
比较的细节在这篇论文里有提,不一一展开。
最终scala选择了采用 样本类(case class) 和 抽取器(extractor) 来实现模式匹配。
我们大致了解一下case class和extractor 是怎么回事
1)样本类(case class)
本质上case class是个语法糖,对你的类构造参数增加了getter访问,还有toString, hashCode, equals 等方法;
最重要的是帮你实现了一个伴生对象,这个伴生对象里定义了apply 方法和 unapply 方法。
apply方法是用于在构造对象时,减少new关键字;而unapply方法则是为模式匹配所服务。
这两个方法可以看做两个相反的行为,apply是构造(工厂模式),unapply是分解(解构模式)。
case class在暴露了它的构造方式,所以要注意应用场景:当我们想要把某个类型暴露给客户,但又想要隐藏其数据表征时不适宜。
2) 抽取器(extrator)
抽取器是指定义了unapply方法的object。在进行模式匹配的时候会调用该方法。
unapply方法接受一个数据类型,返回另一数据类型,表示可以把入参的数据解构为返回的数据。
比如
class A
class B(val a:A)
object TT {
def unapply(b:B) = Some(new A)
}
这样定义了抽取器TT后,看看模式匹配:val b = new B(new A); b match{ case TT(a) => println(a) }
直观上以为 要拿b和TT类型匹配,实际被翻译为 TT.unapply(b) match{ case Some(…) => … }
它与上面的case class相比,相当于自己手动实现unapply,这也带来了灵活性。
后续会专门介绍一下extrator,这里先看一下extractor怎么实现case class无法实现的”表征独立”(representation independence)
比如我们想要暴露的类型为A
//定义为抽象类型
trait A
//然后再实现一个具体的子类,有2个构造参数
class B (val p1:String, val p2:String) extends A
//定义一个抽取器
object MM{
//抽取器中apply方法是可选的,这里是为了方便构造A的实例
def apply(p1:String, p2:String) : A = new B(p1,p2);
//把A分解为(String,String)
def unapply(a:A) : Option[(String, String)] = {
if (a.isInstanceOf[B]) {
val b = a.asInstanceOf[B]
return Some(b.p1, b.p2)
}
None
}
}
这样客户只需要通过 MM(x,y) 来构造和模式匹配了。客户只需要和MM这个工厂/解构角色打交道,A的实现怎么改变都不受影响。
注:
有很多的资料里在介绍case class时经常把它和函数式语言里的代数数据类对比(ADT)
严格的说Scala中的case class并不是ADT,但比较靠近,可以模拟ADT。
这篇文章中提到case class介于类继承和代数数据类型之间 http://blog.csdn.net/jinxfei/article/details/4677359
提到:”Scala则提供了一种介于两者之间(类继承和代数数据类型),被称为条件类(case classes)的概念”
《Programming in Scala》中文版,在术语表中有提到ADT:
通过提供若干个含有独立构造器的备选项(alternative)来定义的类型。通常可以辅助于通过模式匹配解构类型的方式。
这个概念可以在规约语言和函数式语言中发现。代数数据类型在Scala中可以用样本类(case class)模拟。
转自:http://ifeve.com/pattern-matching-2/
scala 模式匹配详解 2 scala里是怎么实现的?的更多相关文章
- scala 模式匹配详解 1
什么是模式? 一些刚从java转到scala的同学在开发的过程中犹如深陷沼泽,因为很多的概念或风格不确定,scala里有很多的坑,模式匹配也算一个.我整理了一下自己所理解的概念,以及一些例子.这个系列 ...
- scala 模式匹配详解 3 模式匹配的核心功能是解构
http://www.artima.com/scalazine/articles/pattern_matching.html这篇文章是odersky谈scala中的模式匹配的一段对话,我做了部分片段翻 ...
- Scala 入门详解
Scala 入门详解 基本语法 Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ; 是可选的 Scala 程序是对象的集合,通过调用彼此的方法来实现消息传递.类,对象,方法,实例变 ...
- KMP字符串模式匹配详解(zz)
刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN A_B_ ...
- KMP字符串模式匹配详解
KMP字符串模式匹配详解 http://www.cppblog.com/oosky/archive/2006/07/06/9486.html
- Spark入门到精通--(第二节)Scala编程详解基础语法
Scala是什么? Scala是以实现scaleable language为初衷设计出来的一门语言.官方中,称它是object-oriented language和functional languag ...
- Scala入门详解
object作为Scala中的一个关键字,相当于Java中的public static class这样的一个修饰符,也就说object中的成员都是静态的! 所以我们在这个例子中的main方法是静态的, ...
- Scala集合类详解
对scala中的集合类虽然有使用,但是一直处于一知半解的状态.尤其是与java中各种集合类的混合使用,虽然用过很多次,但是一直也没有做比较深入的了解与分析.正好趁着最近项目的需要,加上稍微有点时间,特 ...
- Scala面向对象详解
Scala的包(作用域) package com.jh.scala 等同于 package jh \n package scala 等同于 package com.jh{ package scala ...
随机推荐
- 在AngularJS中实现一个延迟加载的Directive
所谓的延迟加载通常是:直到用户交互时才加载.如何实现延迟加载呢? 需要搞清楚三个方面: 1.html元素的哪个属性需要延迟加载?2.需要对数据源的哪个字段进行延迟加载?3.通过什么事件来触发延迟加载? ...
- .Net Core URL编码和解码
一.URL说明 .Net Core中http 的常用操作封装在 HttpUtility 中 命名空间 using System.Web; // // 摘要: // Provides methods f ...
- Caffe使用step by step:caffe框架下的基本操作和分析
caffe虽然已经安装了快一个月了,但是caffe使用进展比较缓慢,果然如刘老师说的那样,搭建起来caffe框架环境比较简单,但是完整的从数据准备->模型训练->调参数->合理结果需 ...
- WPF腾讯视频通话开发
一.IntPtr.HandleC#中的IntPtr类型称为“平台特定的整数类型”,它们用于本机资源,如窗口句柄. 1.WPF窗口句柄IntPtr wnip = new System.Windows.I ...
- awesomes前端资源库网站
https://www.awesomes.cn http://www.cnblogs.com/jiujiaoyangkang/p/4998518.html (web app自适应框架flexible) ...
- idea 自动导入包 快捷键
idea可以自动优化导入包,但是有多个同名的类调用不同的包,必须自己手动Alt+Enter设置 设置idea导入包 勾选标注 1 选项,IntelliJ IDEA 将在我们书写代码的时候自动帮我们优化 ...
- python3用BeautifulSoup抓取id='xiaodeng',且正则包含‘elsie’的标签
# -*- coding:utf-8 -*- #python 2.7 #XiaoDeng #http://tieba.baidu.com/p/2460150866 #使用多个指定名字的参数可以同时过滤 ...
- java的impl
java impl 是一个资源包,用来存放java文件的. 在Java开发中,通常将后台分成几层,常见的是三层mvc:model.view.controller,模型视图控制层三层,而impl通常处于 ...
- Android——SQLite/数据库 相关知识总结贴
android SQLite简介 http://www.apkbus.com/android-1780-1-1.html Android SQLite基础 http://www.apkbus.com/ ...
- 11G新特性 -- 收缩临时表空间
当大任务执行完毕,并不会立即释放临时表空间.有时候通过删除然后重建临时表空间的速度可能更快.不过对于在线系统可能不会那么容易删除重建,所以11g中可以在线收缩临时表空间或单个临时数据文件. 收缩临时表 ...