`
zhangxiong0301
  • 浏览: 351070 次
社区版块
存档分类
最新评论

模式匹配与样例类

 
阅读更多

Scala强大的模式匹配机制,可以应用在switch语句、类型检查以及“析构”等场合。样例类对模式匹配进行了优化。

更好的switch

 

上面代码中,case _模式对应于switch语句中的default,能够捕获剩余的情况。如果没有模式能匹配,会抛出MatchError。而且不像常见的switch语句,在一种模式匹配之后,需要使用break来声明分支不会进入下一个分支。

match是表达式,不是语句,所以是有返回值的,故可将代码简化:

match表达式中可以使用任何类型。模式总是从上往下进行匹配。

守卫

看代码就好,与if表达式的守卫相同作用:

 

模式中的变量

如果在case关键字后跟着一个变量名,那么匹配的表达式会被赋值给那个变量。case _是这个特性的一个特殊情况,变量名是_。

经过我的尝试,在如果变量名是_,那么在=>后使用_是不行的。

在模式中使用变量可能会与常量冲突。

在上面的代码中,要如何判断Pi这个标志符是一个用来匹配的常量还是模式中的变量?规则是:变量比需要以小写字母开始。如果有常量是小写字母开头的,那么需要用反引号将常量名包起来:

 

类型模式

相比使用isInstanceOf来判断类型,使用模式匹配更好。

在匹配类型时,需要使用一个变量名,否则就是使用对象本身来进行匹配了。

因为匹配是发生在运行期的,而且JVM中泛型的类型信息会被擦掉,因此不能使用类型来匹配特定的Map类型(大部分集合类型也都不可以吧):

但对于数组来说,类型信息是完好的,所以可以在Array上匹配。

匹配数组、列表和元组

 

下面的模式匹配,功能与上面的代码是一样的,不过将数组换成了列表。

与上面两个例子差不多,模式匹配也可以使用在元组上。

注意到变量将会被绑定到这三种数据结构的不同部分上,这种操作被称为“析构”。

提取器

在上一节中,使用模式匹配来对数组、列表和元组进行了匹配,在这个过程的背后的是提取器(extractor)机制。使用unapply来提取固定数量的对象,使用unapplySeq来提取一个序列。

在前面的代码 case Array(0, x) => ...中, Array(0, x)部分实际上是使用了伴生对象中的提取器,实际调用形式是: Array.unapplySeq(arr)。根据Doc,提取器方法接受一个Array参数,返回一个Option。

正则表达式是另一个适用提取器的场景。正则有分组时,可以用提取器来匹配分组:

 

变量声明中的模式

在变量声明中的模式对于返回对偶(更广一点也可以用在元组上吧?)的函数来说很有用。

 

for表达式中的模式

这一部分的内容多在介绍for表达式时提过了,不过当时并没有意识到使用的是模式。

 

样例类

样例类是种特殊的类,经过优化以用于模式匹配。

使用:

在声明样例类时,下面的过程自动发生了:

  • 构造器的每个参数都成为val,除非显式被声明为var,但是并不推荐这么做;
  • 在伴生对象中提供了apply方法,所以可以不使用new关键字就可构建对象;
  • 提供unapply方法使模式匹配可以工作;
  • 生成toString、equals、hashCode和copy方法,除非显示给出这些方法的定义。

除了上述之外,样例类和其他类型完全一样,方法字段等。

copy方法和带名参数

样例类的copy方法创建一个与现有对象相同的新对象。可以使用带名参数来修改某些属性:

 

case语句中的中置表示法

如果unapply方法产出一个对偶,则可以在case语句中使用中置表示法。对于有两个参数的样例类,可以使用中置表示法。

这个特性的本意是要匹配序列。举例,List对象要么是Nil,要么是样例类::。所以可以:

多个中置表达式放在一起时会比普通的形式更加易读。

匹配嵌套结构

这个解释起来有点绕。

模式可以匹配到特定的嵌套:

上面的代码中descr这个变量被绑定到第一个Article的description。另外还可以使用@来将值绑定到变量:

下面是个使用了模式匹配来递归计算Item价格的函数。

 

密封类

当使用样例类来做模式匹配时,如果要让编译器确保已经列出所有可能的选择,可以将样例类的通用超类声明为sealed。

密封类的所有子类都必须在与该密封类相同的文件中定义。

如果某个类是密封的,那么在编译期所有的子类是可知的,因而可以检查模式语句的完整性。

让所有同一组的样例类都扩展某个密封的类或特质是个好的做法。

模拟枚举

可以使用样例类来模拟枚举类型:

 

Option类型

Option类型用来表示可能存在也可能不存在的值。样例子类Some包装了某个值,而样例对象None表示没有值。Option支持泛型。

 

偏函数(L2)

被包在花括号内的一组case语句是一个偏函数。

偏函数是一个并非对所有输入值都有定义的函数,是PartialFunction[A, B]类的一个实例,其中A是参数类型,B是返回类型。该类有两个方法:apply方法从匹配的模式计算函数值;isDefinedAt方法在输入至少匹配其中一个模式时返回true。

 

分享到:
评论

相关推荐

    scala的匹配样例类

    scala可以使用模式匹配来匹配样例类,从而可以快速获取样例类中的成员数据。后续,我们在开发Akka案例时,还会用到。 示例 需求说明 创建两个样例类Customer、Order Customer包含姓名、年龄字段 Order包含id字段 ...

    4.样式类和模式匹配1

    1. 样例类 case class 和模式匹配 pattern matching 是一组孪生语法,它们为我们编写规则的、 1. 样例类是 Scala 用于对象模

    快学 scala 语法大全

    此文档是scala的语法大全,一共分为22章,控制结构,特质,高阶函数,集合,模式匹配,样例类,解析,actor等都包括在内。

    Scala快速入门(适合为学Spark学习Scala的同学)

    scala安装使用、scala基础、scala方法与函数、scala tuple/集合/list/字符串/set/map、、trait特性、模式匹配、隐式转换、样例类、actorModal

    快学 scala 中文版 带完整目录

    第14章 模式匹配和样例类 A2 221 14.1 更好的switch 222 14.2 守卫 223 14.3 模式中的变量 223 14.4 类型模式 224 14.5 匹配数组、列表和元组 225 14.6 提取器 227 14.7 变量声明中的模式 227 14.8 for...

    MyScala.rar

    Scala _02基础,Scala _03方法与函数,Scala _04Scala字符串,Scala _05集合_数组,Scala _07trait特性,Scala _08模式匹配match&偏函数,Scala _09样例类(case classes)&隐式转换,Scala _10Actor Model

    SeimiCrawler文档离线版

    第一个爬虫规则类-crawler ◾5.2.1.注解@Crawler ◾5.2.2.实现startUrls() ◾5.2.3.实现start(Response response) ◾5.2.4.Response数据提取 ◾5.2.4.1.内部属性一览 ◾5.2.5.回调函数 ◾5.2.6.Request内部...

    antlr4权威指南

    我甚至为一次演讲编写了一个简单的DNA模式匹配程序。  一门语言的正式描述称为语法(grammar),ANTLR能够为该语言生成一个语法分析器,并自动建立语法分析树——一种描述语法与输入文本匹配关系的数据结构。ANTLR...

    【。net 专业】 面试题

    类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而不是引用类型,并且结构不支持继承。结构的值存储在“在堆栈上”或“内联”。细心的...

    asp.net面试题

    类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而不是引用类型,并且结构不支持继承。结构的值存储在“在堆栈上”或“内联”。细心的...

    Microsoft SQL Server 2008技术内幕:T-SQL查询(第二卷)

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》内容丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性很强,可以把它们作为解决实际问题的标准模式。阅读《Microsoft SQL Server 2008技术内幕:T-SQL...

    Maven权威指南 很精典的学习教程,比ANT更好用

    下载本章样例 4.2. 定义Simple Weather项目 4.2.1. Yahoo! Weather RSS 4.3. 创建Simple Weather项目 4.4. 定制项目信息 4.5. 添加新的依赖 4.6. Simple Weather源码 4.7. 添加资源 4.8. 运行Simple ...

    SQLServer2008技术内幕T-SQL查询包含源代码及附录A

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》内容丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性很强,可以把它们作为解决实际问题的标准模式。阅读《Microsoft SQL Server 2008技术内幕:T-SQL查询...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录 中文版

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》内容丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性很强,可以把它们作为解决实际问题的标准模式。阅读《Microsoft SQL Server 2008技术内幕:T-SQL查询...

    代码语法错误分析工具pclint8.0

    1.将pclint.rar解压至c:\, 这样lint文件就位与c:\pclint(安装目录)下了。 2.将c:\pclint\lnt 下的3个文件lib-w32.lnt,env-vc6.lnt,co-msc60.lnt拷贝至c:\pclint下, 再在安装目录下创建std.lnt和options.lnt两个...

Global site tag (gtag.js) - Google Analytics