话说模式匹配(8) 一个抽取器的例子

一个抽取器的例子

目前List的序列模式(sequence pattern)可以支持对前边若干元素的匹配,比如:List(1,2,3,_*),如果想要实现 List(_*, lastEle) 这样的形式,就需要通过自定义一个抽取器来实现了

// 自定义Extractor
object Append {
 // 接受List结构
 def unapply[A] (l: List[A]) = {
 // 返回Tuple2:前边的若干元素和最后一个元素
 Some( (l.init, l.last) )
 }
}

抽取器里的unapply方法,入参对应你想要进行匹配的对象,出参则是解构后的元素。
比如 list match { case Append(x,y) => } 里面的list对应unapply的入参,x,y对应unapply方法的出参。

为什么unapply方法的返回结果大多都使用Some包装一下,这其实是unapply方法返回值的一些约束

  1. 返回Boolean,那么匹配时 case A() 里面的true不用写(也不能写)
  2. 若原本想要返回类型为T,则使用Option[T],这样是为了匹配时能够判断是否成功,Some[T] 成功,None不成功
  3. 若原本想要返回一组T1,…Tn,则使用Option[(T1,…Tn)]

现在看看上面自定义抽取器的使用例子:

scala> (1 to 9).toList match{ case _ Append 9 => println("OK") }
OK

scala> (1 to 9).toList match{ case x Append 8 Append 9 => println("OK") }
OK

上面使用了中缀写法,也可以写成普通的构造方式,只是看起来没有上面的舒服

scala> (1 to 9).toList match{ case Append(Append(_,8),9) => println("OK") }
OK

另外,如果觉得Append这个名字太啰嗦,抽取器object单例名称也可以用符号表达,比如用”:>“来表示

object :> {
 // unapply ...
}

这样对匹配时的表达显得更简短一些

scala> (1 to 9).toList match{ case x :> 8 :> 9 => println("OK") }
OK

另外,以”:“结尾的符号支持从右到左的操作方式,List的子类就采用了“::”这样的名称,以方便模式匹配(当然也是因为早期的一些函数式语言里,如ML里已经定义了::的形式,scala只是延续而已)。

文章转自 并发编程网-ifeve.com

时间: 2024-11-16 22:21:36

话说模式匹配(8) 一个抽取器的例子的相关文章

话说模式匹配(7) 一个构造器模式的例子(by case class)

在第一篇讲述构造器模式匹配的时候给出过tree的例子,因为tree的数据结构很适合用构造器模式来解构.这次再看另一个例子. scala里的List是个典型的很适用模式匹配的结构,它的接口和数据定义非常凝练.现在我们假设需要一个与List结构正好相反的结构MyList. List由2部分组成,[head, tail],其中的head是元素本身,而tail则是List类型,也就是一种递归结构. MyList也由2部分组成 [init, last],其中last是元素本身,而init则是MyList类

话说模式匹配(2) scala里是怎么实现的?

在这篇martin和另外两位模式匹配领域专家的论文里说了模式匹配的几种实现方式,以及scala是选择哪种方式来实现的. http://lampwww.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf 我引用了里面的一些描述. 在面向对象的程序中数据被组织为一级一级的类(class) 面向对象语言在模式匹配方面的问题在于如何从外部探测这个层级. 有6种实现模式匹配的方法: 1) 面向对象的分解 (decomposition) 2) 访

话说模式匹配(1) 什么是模式?

一些刚从java转到scala的同学在开发的过程中犹如深陷沼泽,因为很多的概念或风格不确定,scala里有很多的坑,模式匹配也算一个.我整理了一下自己所理解的概念,以及一些例子.这个系列最好有些scala的基本经验,或者接触过一些其他函数式语言. 要理解模式匹配(pattern-matching),先把这两个单词拆开,先理解什么是模式(pattern),这里所的模式并不是设计模式里的模式. 而是数据结构上的,这个模式用于描述一个结构的组成. 我们很容易联想到"正则表达"里的模式,不错,

关于Java中的继承和组合的一个错误使用的例子

关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚,论证不清晰,欢迎大家留言指正. 什么是「组合」和「继承」 假设有2个class:A和B: 如果class A extends B 那么我们就说A继承B,A是子类,B是父类,这种情况就是继承. 如果A中有一个属性的类型为B,那么我们就说这种情况就是组合. 分别在什么情况下使用 回想一些我们一般会在什么情况下考虑这

以一个最简单的例子把OO的JavaScript说明白

javascript  OO的JavaScript并不高深,麻烦就麻烦在google出来的国人介绍文章经常罗罗嗦嗦,而且之间的说法还各有不同,摆在一起就让人看了头大.这里重拾简单主义,以一个最简单的例子把OO Javascript说明白. 1.一个颇为精简的例子 //定义Circle类function Circle(radius) {    this.r = radius;}Circle.PI = 3.14159;Circle.prototype.area = function(  ) {ret

一个可逆加密的例子

加密     下面的代码实现了一个可逆加密的方法.可以用于对Cookie,QueryString等加密处理.      查看例子      VB.net代码      <%@ Page Language="vb" AutoEventWireup="false" Codebehind="EncString.<a href="http://dev.21tx.com/web/asp/" target="_blank&qu

羽翼随机抽取器如何使用教程

  羽翼随机抽取器是一款适用于所有会议,抽奖,课堂等等的软件工具,想要知道羽翼随机抽取器如何使用教程吗?下面就由小编为大家讲解一下使用的方法吧. 1.解压缩并安装软件 2.首先选择需要抽取的类型 3.系统设置支持各种设置的修改 4.设置完成后直接点击操作选项的[开始抽取] 这款软件,不管大家是平时在游戏中进行抽奖还是会议抽奖都非常适合哦,能够为用户带来不少便利,欢迎有需要的朋友下载使用!

.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(一)

引言 随着CPU多核的普及,编程时充分利用这个特性越显重要.本文首先用传统的嵌套循环进行数组填充,然后用.NET 4.0中的System.Threading.Tasks提供的Parallel Class来并行地进行填充(当然这里也用到嵌套循环),通过对比发现其中差异.主要内容如下: 通常的数组填充 并行的组数填充 性能比较 System.Threading.Tasks分析,这个将在续篇.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(二)中介绍 1.通

jquery插件-jquery.bootgrid插件如何实现数据的分页显示,求一个简单地小例子~~

问题描述 jquery.bootgrid插件如何实现数据的分页显示,求一个简单地小例子~~ 感觉它是一个非常不错的数据分页显示框架,希望能够学会,可是在网上没有查到类似的资料,大家有用过的吗? 解决方案 http://www.jquery-bootgrid.com/Examples 解决方案二: 这个我看过了,但是代码不全,有部分不知道怎么写