Scala中的Extractor
Scala中使用unapply方法可以实现三种extractor(另外使用unapplySeq也可以实现extractor)
- def unapply(object: S): Option[(T1, ..., Tn)]
- def unapply(object: S): Option[T]
- 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) => ...
}
问题是:
- 怎么理解返回值为Boolean的extractor呢?
- 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的更多相关文章
- 理解Scala中的Extractor
引言 最近抱着<Programming in Scala>(英文第二版)在死啃Scala.在阅读第26章Extractor时,偶然在Stack Overflow上搜到一个帖子<Sca ...
- Scala中apply的用法
Scala中的 apply 方法有着不同的含义, 对于函数来说该方法意味着调用function本身, 以下说明摘自Programming in Scala, 3rd Edition Every fun ...
- scala中的面向对象定义类,构造函数,继承
我们知道scala中一切皆为对象,函数也是对象,数字也是对象,它是一个比java还要面向对象的语言. 定义scala的简单类 class Point (val x:Int, val y:Int) 上面 ...
- Scala中的None,Nothing,Null,Nil
在scala中这四个类型名称很类似,作用确实完全不同的. None是一个object,是Option的子类型,定义如下 case object None extends Option[Nothing] ...
- Scala中Iterator允许执行一次
背景 使用spark执行mapPartitionsWithIndex((index,iterator)=>{....}),在执行体中将iterator进行一次迭代后,再次根据iterator执行 ...
- 第52讲:Scala中路径依赖代码实战详解
今天学习了scala中的路径依赖,来看一下实战代码 class Outer{ private val x = 10 class Inner{ private val y = x +10 } ...
- 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用
今天学习了下scala中的链式调用风格的实现,在spark编程中,我们经常会看到如下一段代码: sc.textFile("hdfs://......").flatMap(_.spl ...
- scala入门教程:scala中的面向对象定义类,构造函数,继承
我们知道scala中一切皆为对象,函数也是对象,数字也是对象,它是一个比java还要面向对象的语言. 定义scala的简单类 class Point (val x:Int, val y:Int) 上面 ...
- Scala 中object和class的区别
Scala中没有静态类型,但是有有“伴侣对象”,起到类似的作用. Scala中类对象中不可有静态变量和静态方法,但是提供了“伴侣对象”的功能:在和类的同一个文件中定义同名的Object对象:(须在同一 ...
随机推荐
- 关于对XE7中introduced in an ancestor and cannot be deleted的解决方案
在Delphi XE7中设计Multi-Device Application 类型窗体中,发现删除一个组件时,提示introduced in an ancestor and cannot be del ...
- win32进阶之路:程序托盘图标+右键弹出菜单
开场白 本次介绍两个非常棒且实用的技巧:程序托盘图标和右键弹出菜单,效果如下图. 程序托盘图标用了迅雷的图标,右键点击时候会弹出三个选项的菜单. 程序托盘图标设置 我会用尽可能清晰明了的步骤介绍方式 ...
- Android 开机自启动应用
Android启动时,会发出一个系统广播 ACTION_BOOT_COMPLETED,它的字符串常量表示为 “android.intent.action.BOOT_COMPLETED” 开机自启动程序 ...
- win7下64位系统memcache/memcached安装教程
折腾了1个多小时,终于搞定.操作系统时64位的,php5.3.13 类似于上一篇的xdebug安装教程~~ memcache和memcached的区别 在自己的新程序中打算全面应用memcached ...
- 常用到的Tomcat的修改方法
1.修改端口号 打开tomcat的service.xml文件: 找到<Connector connectionTimeout="20000" port="8080& ...
- 定制的Server-Sent Events 聊天服务器
//匿名聊天服务器 //将新的消息POST到/chat地址,或者以GET形式从通一个URL获取文本或事件流 //创建一个GET请求到"/"来返回一个简单的HTML文件,这个文件包括 ...
- 指针与strncpy---内存
指针的形式的赋值和strncpy的赋值 e.SetAttr("Amt", ToString(dAmt) ); e.SetAttr("Amt", sAm ...
- 用于主题检测的临时日志(594fb726-af0b-400d-b647-8b1d1b477d72 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
这是一个未删除的临时日志.请手动删除它.(f8322da6-c527-47fb-98d2-f12a7d814d19 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
- [java学习笔记]java语言基础概述之转义字符&break&continue
1.转义字符 \t:制表符 \n:回车 \b:退格 \r:回车 \":双引号 \\:反斜线(常用于文件路径的书写中) windows系统中回车符其实是由两个符号组成的,\r\n linu ...
- python 自动化之路 day 10 协程、异步IO、队列、缓存
本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Twsited网络框架 引子 到目 ...