Scala中使用unapply方法可以实现三种extractor(另外使用unapplySeq也可以实现extractor)

  1. def unapply(object: S): Option[(T1, ..., Tn)]
  2. def unapply(object: S): Option[T]
  3. def unapply(object: S): Boolean

感觉第三种extractor的使用形式有些奇怪。比如,下面是《快学Scala》中的一个例子:

object Name {
def unapply(input: String) = {
val pos = input.indexOf(" ")
if(pos == -1) None
else Some(input.substring(0, pos), input.substring(pos + 1))
}
}
object IsCompound {
def unapply(input: String) = input.contains(" ")
}

  这里定义了两个extractor: Name和IsCompound, 前者返回Option[String], 后者返回Boolean

可以这么使用这两个extractor

author match {
case Name(first, last @ IsCompound()) => ...
case Name(first, last) => ...
}

问题是:

  1. 怎么理解返回值为Boolean的extractor呢?
  2. IsCompound()后边的()不能省略,也不能像返回option的extractor一样绑定变量,比如IsCompound(isComp), 该怎么理解这种行为呢?

在这篇文章

The Neophyte's Guide to Scala Part 1: Extractors

里找到了答案。


之所以觉得这种形式比较奇怪,还是对extractor的概念理解得有些模糊,没有搞清楚那种match的形式到底干了个啥。

拿最简单的形式为例

object Test extends App{
val author = "Dan Simmons"
author match{
case Name(firstName, lastName) => println(s"""Hello, Mr $lastName""")
case _ =>
}
}

输出:Hello, Mr Simmons

首先这是一个pattern matching。当某个case分支匹配成功后,就会执行 =>后的语句。

那什么样算是匹配成功呢?

这就跟具体的extractor有关了,对于返回Option的提取器,如果调用unapply方法成功返回Some,就算是成功。对于返回Boolean的提取器,如果调用unapply方法返回true,那就是匹配成功。

在这个pattern matching里,第一个case使用的Name这个提取器匹配成功,它对author这个字符串进行了“解构”,其结果是定义了两个新的变量:firstName和lastName。

当使用返回Boolean的extractor时,我们并不是进行解构,而是进行判断。因此,返回Boolean的extractor在进行匹配后,不会定义新变量;但是为了与类型匹配分开,也不能直接用提取器的名字而不跟括号。 返回Boolean的提取器,在使用时,只能使用extractor的名字加上()这种形式。像下面这样

  author match{
case IsCompound() => println("is compound")//IsCompound()里的()不能省
case _ =>
}

也可以把这两种extractor混合起来

  author match{
case Name(first, last @ IsCompound()) => println("has a compound last name")
case Name(first, last) => println("don't has a compound name")
case _ =>
}

第一个case是一种复合匹配,只有当Name这个extractor匹配成功,并且提取出来的第二个变量匹配成功IsCompound()时,整个模式才会匹配成功。在这里@定义了一个变量last,把它绑定到成功匹配了IsCompound的那个值上。

Scala中的Extractor的更多相关文章

  1. 理解Scala中的Extractor

    引言 最近抱着<Programming in Scala>(英文第二版)在死啃Scala.在阅读第26章Extractor时,偶然在Stack Overflow上搜到一个帖子<Sca ...

  2. Scala中apply的用法

    Scala中的 apply 方法有着不同的含义, 对于函数来说该方法意味着调用function本身, 以下说明摘自Programming in Scala, 3rd Edition Every fun ...

  3. scala中的面向对象定义类,构造函数,继承

    我们知道scala中一切皆为对象,函数也是对象,数字也是对象,它是一个比java还要面向对象的语言. 定义scala的简单类 class Point (val x:Int, val y:Int) 上面 ...

  4. Scala中的None,Nothing,Null,Nil

    在scala中这四个类型名称很类似,作用确实完全不同的. None是一个object,是Option的子类型,定义如下 case object None extends Option[Nothing] ...

  5. Scala中Iterator允许执行一次

    背景 使用spark执行mapPartitionsWithIndex((index,iterator)=>{....}),在执行体中将iterator进行一次迭代后,再次根据iterator执行 ...

  6. 第52讲:Scala中路径依赖代码实战详解

    今天学习了scala中的路径依赖,来看一下实战代码 class Outer{  private val x = 10  class Inner{    private val y = x +10  } ...

  7. 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用

    今天学习了下scala中的链式调用风格的实现,在spark编程中,我们经常会看到如下一段代码: sc.textFile("hdfs://......").flatMap(_.spl ...

  8. scala入门教程:scala中的面向对象定义类,构造函数,继承

    我们知道scala中一切皆为对象,函数也是对象,数字也是对象,它是一个比java还要面向对象的语言. 定义scala的简单类 class Point (val x:Int, val y:Int) 上面 ...

  9. Scala 中object和class的区别

    Scala中没有静态类型,但是有有“伴侣对象”,起到类似的作用. Scala中类对象中不可有静态变量和静态方法,但是提供了“伴侣对象”的功能:在和类的同一个文件中定义同名的Object对象:(须在同一 ...

随机推荐

  1. 动态sql语句基本语法

    1 普通sql语句可以用exec执行,如: SELECT * FROM video EXEC ('SELECT * FROM video') EXEC sp_executesql N'SELECT * ...

  2. Xcode7网络问题

    更新Xcode7以后运行模拟器,控制台打印:Application Transport Security has blocked a cleartext HTTP (http://) resource ...

  3. MAC系统介绍

    MACOS: UNIX系统图形界面的显示 开发环境: 一种是终端(terminal) 一种是Xcode(ide) MAC快捷键: command(window) + c : 复制 command + ...

  4. 百度云管家-V4.6.1-单文件版绿色版

    转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/baidu-is-clouds-butler-v4-6-1-single-file-green-edition ...

  5. SVN全量备份+增量备份脚本

    一.全量备份 环境:一台主SVN,一台备SVN(主要提供备份功能),后续可通过钩子脚本进行实时备份,后续发给大家. 工作原理:通过svn的hotcopy命令过行热备份,并进行一系列的检查,备份后通过r ...

  6. thinkphp3.2引入php 实例化类

    如果你的类库没有采用命名空间的话,需要使用import方法先加载类库文件,然后再进行实例化,例如:我们定义了一个Counter类(位于Com/Sina/Util/Counter.class.php): ...

  7. JAVA中的代理技术(静态代理和动态代理)

    最近看书,有两个地方提到了动态代理,一是在Head First中的代理模式,二是Spring AOP中的AOP.所以有必要补充一下动态代理的相关知识. Spring采用JDK动态代理和CGLib动态代 ...

  8. C# 获取中文星期的两种方法

    //方法一 public string Week() { string[] weekdays = { "星期日", "星期一", "星期二" ...

  9. JS实现图片翻书效果示例代码

    js 图片翻书效果.  picture.html  <html xmlns="http://www.w3.org/1999/xhtml">  <head>  ...

  10. C# 学习之旅(2)--- 意外的收获

    今天在完成老师布置的C#作业(计算一元二次方程的根)的时候,收获到意外的知识,所以写此博文予以记录. 意外收获为: 对文本框的输入值进行检测,使之按照要求格式输入. 下面是整个的源代码: using ...