http://www.artima.com/scalazine/articles/pattern_matching.html
这篇文章是odersky谈scala中的模式匹配的一段对话,我做了部分片段翻译(不是连贯的):

模式可以嵌套,就像表达式嵌套,你可以定义深层的模式,通常一个模式看起来就像一个表达式。它基本上就是同一类事情。
它看起来像一个复杂的对象树构造表达式,只是漏掉了new关键字。事实上在scala当你构造一个对象,你不需要new关键字
然后你可以在一些地方用变量做站位符替代对象树上实际的东西。

本质上,当你需要通过外部来构造对象图,模式匹配是必要的,因为你不能对这些对象添加方法
有很多场景的例子,XML是一个,所有解析过的数据落入不同的分类。
举例,一个标准的场合是当你用编译器解析抽象语法树的时候模式匹配是必要的。

解构对象 (De-constructing objects)
Bill Venners: 你说模式像表达式,但它更像“逆表达式”,不同于插入值并得到结果(构造一个对象的过程),你放入一个值,当它匹配,一串值弹出来。
Martin Odersky: 是的,它确实是反向构造,我可以通过嵌套的构造器来构造对象。我有一个方法一些参数,通过这些参数可以构造出负责的对象结构。模式匹配正好相反,它从一个复杂的对象结构中抽出原来用于构造这个对象的参数

可扩展性的两个方向(Two directions of extensibility)

扩展性的另一个概念是数据结构相对固定,你不想改变它,但你想要用到的行为操作是开放的。你随时都想要添加新的操作。
典型的例子是编译器,编译器用语法树表达你的程序,只要你没有改变你的语言,语法树就不会变,一直都是同一颗树
但编译器想要这棵语法树每天改变。明天你或许想到一种新的优化在遍历树的阶段。

所以,你想采取的办法是操作定义在你的语法树外部,否则你要不断的添加新方法

这个工作正确的方向,取决于你想在那个方向扩展,如果你想要扩展新的数据,你选择经典的面向对象通过虚方法调用实现。如果你想保持数据固定,扩展新的操作,模式更适合。
实际上有一个设计模式,不要和模式匹配混淆,在面向对象程序中称为“访问者模式”,也可以用面向对象的方式表达模式匹配的方式,基于虚方法委派的。

但实际中用visitor模式是非常笨重的,不能像模式匹配那样轻松的做很多事。你应该终结笨重的vistors,同时在现代虚拟机技术中也证明vistor模式远没有模式匹配有效。所有这些原因,我想应该为模式匹配定义一套规则

ps, 前段时间王垠同学在批判设计模式的一篇文章中,提到visitor模式就是模式匹配。
可以对比一下scala语言通过case class/extractor方式在语言级别支持模式匹配,与通过visitor模式来达到同样的效果时的代码差别。

转自:http://ifeve.com/pattern-matching-3/

scala 模式匹配详解 3 模式匹配的核心功能是解构的更多相关文章

  1. scala 模式匹配详解 1

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

  2. KMP字符串模式匹配详解(zz)

    刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN     A_B_ ...

  3. KMP字符串模式匹配详解

    KMP字符串模式匹配详解 http://www.cppblog.com/oosky/archive/2006/07/06/9486.html

  4. ES6,ES2105核心功能一览,js新特性详解

    ES6,ES2105核心功能一览,js新特性详解 过去几年 JavaScript 发生了很大的变化.ES6(ECMAScript 6.ES2105)是 JavaScript 语言的新标准,2015 年 ...

  5. Scala 入门详解

    Scala 入门详解 基本语法 Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ; 是可选的 Scala 程序是对象的集合,通过调用彼此的方法来实现消息传递.类,对象,方法,实例变 ...

  6. Java & Groovy & Scala & Kotlin - 20.Switch 与模式匹配

    Overview 本章主要介绍高级条件语句中的 switch 语句以及其增强版的模式匹配. Java 篇 Switch 特点 Java 中 switch 语句功能类似 if,但是 switch 主要用 ...

  7. RocketMQ详解(四)核心设计原理

    专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...

  8. 详解MathType引用公式编号功能

    在论文创作期间,如果需要在文本中删除大量的公式,手动编号删除的工作量是比较大的,使用MathType引用公式编号功能就可以节约大量的时间,提供很大的方便.本教程将详解MathType引用公式编号功能. ...

  9. 带连接池的netty客户端核心功能实现剖解

    带连接池的netty客户端核心功能实现剖析 带连接池的netty的客户端核心功能实现剖析 本文为原创,转载请注明出处 源码地址: https://github.com/zhangxianwu/ligh ...

随机推荐

  1. 实战:mysql统计指定架构的全部表的数据和索引大小情况-v2

    PS:第一个版本号里未做输入的schema_name和table_name推断,改动了一下!再次share! #统计指定架构的全部表的数据和索引大小情况 #tablesize.sh #!/bin/sh ...

  2. .NET:race conditions

    race conditions (when an anomalous result occurs due to an unexpected critical dependence on the tim ...

  3. WPF 实现阴影效果

    一.WPF最常见的一个阴影效果的类是DropShadowEffect.它有几种比较有用的属性比如:Color设置颜色Direction设置投影的方向ShadowDepth设置投影距纹理下方的距离Opa ...

  4. EF迁移命令

    EF迁移设置的最后一步是在包管理器控制台中输入命令“add-migration InitialMigration -IgnoreChanges”.“InitialMigration”(高亮的黄色)是您 ...

  5. CSS中的偏僻知识点

    一.css中的calc 在CSS中有calc属性用于尺寸的计算,可以让百分比和像素值进行运算. div {width : calc(100% - 30px);} 为了兼容性 /*Firefox*/ - ...

  6. 五分钟搞清楚MySQL事务隔离级别

    好久没碰数据库了,只是想起自己当时在搞数据库的时候在事务隔离级别这块老是卡,似懂非懂的.现在想把这块整理出来,尽量用最简洁的语言描述出来,供新人参考. 首先创建一个表account.创建表的过程略过( ...

  7. 【转载】js关闭当前页面(窗口)的几种方式总结

    1. 不带任何提示关闭窗口的js代码 复制代码代码如下: <a href="javascript:window.opener=null;window.open('','_self'); ...

  8. oracle登陆提示“ora-01031 insufficient privileges”

    本机装了服务端的oracle11.2g,一直没用,中间换过系统的登陆用户.今早发现登陆数据库时发现老提示“ora-01031 insufficient privileges”,以为监听没配置好,试过了 ...

  9. WEBAPI 的简单示例

    一.webapi 1.在webapiconfig中移除xml的返回格式,返回格式就自动使用Json格式 config.Formatters.Remove(config.Formatters.XmlFo ...

  10. 同一个脚本在SQLPLUS和SQLDEV上的不同

    前几天收集了信息给Oracle.oracle那边表示格式不正确.让我又一次收集.我非常费解,我是依照官方文档做的呀,怎么会? 于是我果断自己搭了一个环境:RHEL5.8+10.2.0.5 客户那边没法 ...