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

模式匹配与样例类

 
阅读更多

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字段 ...

    Scala样例类练习.docx

    #### 七、样例类与特质的结合 ```scala trait Sex case object Male extends Sex case object Female extends Sex case class Student7(name: String, sex: Sex) object Demo7 { def main(args: Array[String]): ...

    4.样式类和模式匹配1

    2. **构造函数模式**:可以匹配样例类实例,如 `case C(a, b)`。 3. **提取器模式**:使用 `unapply` 方法定义的自定义模式,可以解析复杂的对象结构。 4. **变量模式**:直接使用变量名作为模式,匹配成功时将值...

    最邻近匹配与测试样例

    最邻近匹配(Nearest Neighbor Matching,NNM)是一种在机器学习、图像处理和模式识别领域广泛应用的技术。在MATLAB环境中,NNM通常用于寻找数据集中与特定查询点最相似的点,以此来进行分类或回归任务。在这个上下...

    大数据课程-Scala编程基础-5.Scala模式匹配_lk_edit.ppt

    本课程内容涵盖多个关键概念,如模式匹配、样例类、隐式函数和异常处理及泛型,这些都是Scala语言强大特性的体现。 首先,Scala的模式匹配是一种强大的控制流构造,类似于Java中的switch语句,但更为灵活。它允许...

    快学 scala 语法大全

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

    《快学Scala》完整版书籍.rar

    12. **模式匹配和样例类**:模式匹配用于解构复杂数据结构,如匹配枚举值、拆解元组等。样例类(Case Class)是Scala中用于简化模式匹配的特殊类,具有默认的构造函数、equals、hashCode和toString方法。 通过学习...

    人工智能-项目实践-C#-c#基于emgu.cv的模板匹配、行人检测等.zip

    模板匹配是一种图像处理技术,用于在大图中寻找与模板图像相似的小区域。在C#中,通过Emgu.CV库可以很容易地实现这一功能。首先,我们需要加载大图和模板图像,然后调用`MatchTemplate`方法进行匹配,最后通过`...

    10个必须收藏的PHP代码样例

    接着初始化cURL资源,设置URL及相关选项:不返回头部信息、开启二进制传输模式、自动引用和跟随重定向。这些设置确保能完整下载任何类型文件。最后,执行cURL请求并将文件保存到本地。 4. **Alexa/Google Page Rank...

    delphi 正则表达式 样例大全

    在处理文本数据和模式匹配时,正则表达式(Regular Expressions)是不可或缺的工具。正则表达式允许程序员通过简洁的语法来匹配、查找、替换和分析字符串中的模式。在Delphi中,我们可以使用TRegEx类来实现正则...

    Scala编程.V.0.81

    Scala编程语言由著名计算机科学家马丁·奥德斯...随着深入学习,你将探索控制结构、数组、元组、类与对象、继承、特质、模式匹配、样例类、函数及抽象化、集合以及隐式转换等高级概念,为Spark开发和阅读源码做好准备。

    JSP使用验证码样例

    提交表单时,服务器会检查用户输入的验证码是否与会话中存储的验证码匹配。如果匹配,登录过程将继续;如果不匹配,用户将收到错误消息并被要求重新输入。 在这个压缩包中,"testRondom"很可能是一个Servlet类的...

    scala编程基础

    - **样例类**:样例类是一种特殊的类,主要用于模式匹配。当定义为样例类时,Scala会自动生成一系列有用的方法,如`equals`、`hashCode`等。 - **Option类型**:用于表示可能为空的值,是Scala处理空值的一种方式。 ...

    深入python样例程序

    3. **面向对象编程**:介绍类的定义、对象的创建与销毁,封装、继承、多态等面向对象的基本概念,以及类的方法(包括构造函数`__init__`、析构函数`__del__`、属性访问器`__getattribute__`等特殊方法)。...

    图片识别样例程序

    在计算机视觉领域,图片识别通常涉及机器学习和深度学习技术,如特征提取、模式匹配或神经网络模型。 描述中提到是“java程序编写的图片识别样例程序,附简单demo仅供参考”,这意味着该程序不仅包含实际的代码实现...

    SparkDemo学习样例

    4. **Scala编程基础**:复习Scala的变量、函数、类、对象、模式匹配等基础语法,这对于编写Spark应用是必要的。 5. **Spark SQL**:学习如何创建DataFrame,执行SQL查询,以及数据转换操作。这在数据分析和ETL...

    快学 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...

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

    - **样例类**:样例类用于伴生对象和模式匹配,可以方便地创建类的实例。 **4. Scala在大数据中的角色** 随着大数据处理的需求增加,Scala在Apache Spark中的核心地位使其变得尤为重要。Spark使用Scala编写,提供...

    待审核的广告营销文本样例.rar

    在这个“待审核的广告营销文本样例”压缩包中,提供了大量可能用于训练模型的数据。 首先,我们要对这些文本进行预处理。预处理是机器学习中的关键步骤,它包括去除无关字符(如标点符号、数字)、词干提取、词形...

    scala的操作笔记

    - **样例类**:样例类是Scala中一种特殊的类,主要用于模式匹配。它们自动实现了许多有用的特性,如`equals`、`hashCode`和`toString`等方法。 #### 总结 Scala作为一种强大的编程语言,以其优雅的语法、丰富的...

Global site tag (gtag.js) - Google Analytics