`

Scala 样本类(case class)和模式匹配(match)学习

 
阅读更多
样本类(case clas)和模式匹配(pattern matching),在编写规范的、无封装数据结构时会用到的构件。对于树型递归数据尤其有用。

一、简单例子:  

abstract class Expr
case class Var(name:String) extends Expr
case class Number(num:Double) extends Expr
case class UnOp(operator : String , arg : Expr) extends Expr
case class BinOp(operator : String , left : Expr , right : Expr) extends Expr


样本类:添加了case的类便是样本类。这种修饰符可以让Scala编译器自动为这个类添加一些语法上的便捷设定。如下:

添加与类名一致的工厂方法。也就是说,可以写成Var("x")来构造Var对象。
样本类参数列表中的所有参数隐式获得了val前缀,因此它被当作字段维护。
编译器为这个类添加了方法toString,hashCode和equals等方法。

模式匹配:

def simplifyTop(expr : Expr) : Expr = expr match{
case UnOp("-" , UnOp("-" , e)) => e
case BinOp("+" , e , Number(0)) => e
case BinOp("*" , e , Number(1)) => e
case _ => expr
}


match对应Java里的switch,但是写在选择器表达式之后。即: 选择器 match {备选项}。

一个模式匹配包含了一系列备选项,每个都开始于关键字case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。

match表达式通过以代码编写的先后次序尝试每个模式来完成计算。类似于UnOp("-" , UnOp("-" , e))这种形式的,是构造器模式匹配。

match与switch的比较:匹配表达式可以被看作Java风格Switch的泛化。

但有三点不同:

1.match是Scala的表达式,始终以值作为结果;
2.Scala的备选项表达式永远不会“掉到”下一个case;
3.如果没有模式匹配,MatchError异常会被抛出。这意味着必须始终确信所有的情况都考虑到了,或者至少添加一个默认情况什么都不做。如 case _ =>

二、模式的种类

通配模式:case _ => 。表示默认的全匹配备选项。通配模式还可以用来忽略对象中不关心的部分。如:case BinOp(_,_,_) => XXX,则表示不关心二元操作符的元素是什么,只是检查是否为二元操作符

常量模式 :仅匹配自身。任何字面量都可以用作常量。包括String类型。另外,任何的val或单例对象也可以被用作常量。如,单例对象Nil是只匹配空列表的模式。

变量模式 :变量模式类似于通配符,可以匹配任何对象。不同点在于,Scala把变量绑定在匹配的对象上。之后就可以使用这个变量操作对象。如:

expr match{
  case 0 => "zero"
  case somethingElse => "not zero" + somethingElse
}

          
有一个注意点:Scala使用了一个简单的文字规则来区分是一个常量还是一个变量:用小写字母开始的简单名被当作是模式变量。

构造器模式:它的存在使得模式匹配真正变得强大。它由名称及若干括号之内的模式构成。如BinOp("+" , e , Number(0))。

序列模式:可以像匹配样本类那样匹配List或Array这样的序列类型。同样的语法现在可以指定模式内任意数量的元素。如:

expr match{
case List(0 , _ , _ ) => println("found it")
case _ => 
}


如果想匹配一个不指定长度的序列,可以指定_*作为模式的最后元素。它能匹配序列中0到任意数量的元素。

元组模式:


def tupleDemo(expr : Any) = 
   expr match {
     case (a , b, c) => println("matched " + a + b + c)
     case _ => 
}


类型模式:可以把它当做类型测试和类型转换的简易替代。例如:

def generalSize(x : Any) = x match{
   case s : String => s.length
   case m : Map[_ , _] => m.size
   case _ => 1
 }


使用:

scala> generalSize(Map(1 -> 'a' , 2 -> 'b'))

res15 : Int = 2


另:在Scala里类型测试和转换的代码很冗长,因为不建议这么做。

模式守卫:模式变量仅允许在模式中出现一次。如:

1 case BinOp("+" , x , x ) => BinOp("*" , x , Number(2))
  这种写法就会出错。可以改成:  case BinOp("+" , x , y ) if x == y => BinOp("*" , x , Number(2))

模式守卫接在模式之后,开始于if。守卫可以是任意的引用模式中变量的布尔表达式。如果存在模式守卫,那么只有在守卫返回true的时候匹配才成功。

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Scala 专题教程 - Case Class和模式匹配-内含源码以及设计说明书(可以自己运行复现).zip

    在Scala中,Case Class是一种特殊的类,它被设计用于模式匹配和数据封装。其特点包括: 1. **自动成员访问**:Case Class的成员默认是公开的,可以直接通过`.`操作符访问。 2. **隐式拷贝功能**:创建Case Class...

    scala语言for循环中的模式匹配

    本文将详细介绍 Scala 语言 for 循环中的六种模式匹配方式:变量模式匹配、常量模式匹配、变量绑定模式匹配、类型模式匹配、构造函数模式匹配和序列模式匹配。 变量模式匹配 在 Scala 语言中,变量模式匹配是最...

    scala正则表达式与模式匹配.doc

    Scala 正则表达式是 Scala 语言中的一种强大工具,用于模式匹配和字符串处理。在 Scala 中,正则表达式可以通过两种方式创建:通过 `r` 方法直接将字符串转换成正则表达式对象,或者直接显式地调用 `Regex` 构造函数...

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

    例如,函数`abs(x: Int)`使用模式匹配和条件守卫来判断一个整数是否为正数或负数,并返回其绝对值。 ```scala def abs(x: Int) = x match { case i: Int if i >= 0 => i case j: Int if j < 0 => -j case _ => ...

    scala pattern match

    1. **案例类(Case Classes)**:这是Scala中一种特殊的类,主要用于模式匹配。它们自动实现了`equals`和`hashCode`方法,以及`toString`方法,非常适合用作模式匹配中的模式。 2. **提取器(Extractors)**:在...

    Scala和设计模式.pdf

    Scala作为一种兼具面向对象和函数式编程特性的现代语言,通过一系列高级语言特性(如模式匹配、类型推断等)使得许多设计模式的实现更加简洁高效。 #### 二、Scala中的设计模式 接下来,我们将具体介绍几种在Scala...

    case-class-generator:在运行时动态定义和加载Scala类。 有助于将JSON模式快速转换为Scala案例类

    运行时代码生成和评估可以在scala.tools.reflect.ToolBox完成,但是每个包只能创建一个类(请参见此)。 因此,现在我正在使用和生成案例类的字节码,并使用自定义类加载器加载新创建的类。 动态生成的类可用于在...

    4.样式类和模式匹配1

    模式匹配和 Java 的 `switch` 语句类似,但更加强大,因为它可以处理更复杂的结构,而且是一个表达式,总是返回一个值。`@unchecked` 注解用于抑制未覆盖模式的检查,防止 `MatchError` 异常。 总的来说,样例类和...

    Scala样例类练习.docx

    在Scala中,样例类(Case Class)是一种特殊类型的类,主要用于模式匹配和不可变数据结构的构建。它们提供了许多便利的功能,如自动实现`equals`、`hashCode`、`toString`等方法,简化了开发者的编码工作量。 #### ...

    学习scala好的项目

    例如,`case class`用于创建模式匹配友好的数据结构,而`trait`则提供了接口和混入(mix-in)多重继承的功能。此外,`Option`类型是Scala处理null安全的一种方式,它强制程序员明确处理空值情况,避免了常见的...

    通过实例学习Either 树和模式匹配

    清单2展示了如何使用Scala的`case`类配合模式匹配来处理颜色。`case`类是一种特殊的轻量级类,它们自动提供`equals()`、`hashCode()`以及模式匹配支持。在这个例子中,我们定义了一个基本的`Color`类,以及三个继承...

    Scala中正则表达式以及与模式匹配结合(多种方式)

    例如,可以根据不同条件匹配和执行不同的操作。 综上所述,Scala中的正则表达式及其与模式匹配的结合,为字符串处理提供了一种强大而灵活的工具。无论是在简单的文本解析还是在复杂的模式匹配场景中,Scala都提供了...

    scala学习资料(带书签)

    3. **模式匹配**:Scala的模式匹配允许你根据值的不同形式执行不同的操作,这是其强大之处,尤其在处理数据解析和case类时。 **进阶篇** 4. **函数式编程**:Scala深受函数式编程的影响,如高阶函数、闭包、柯里化...

    scala深入学习

    例如,"Objects and Classes" 部分将会讲解类的定义、单例对象、伴生对象(companion objects)、case类以及模式匹配等概念。 4. 特质(Traits):特质在Scala中扮演着极其重要的角色,它们可以被看作是包含方法和...

    Scala设计模式

    通过以上几种设计模式的例子可以看出,Scala支持各种面向对象和函数式的设计模式,这些模式有助于编写更高质量、更灵活、更容易维护的代码。在实际开发中,根据项目的具体需求选择合适的设计模式是非常重要的。

    Scala模式匹配.md

    Scala模式匹配.md

    scala学习源代码

    "示例,或者可能包含一些更复杂的案例,如函数定义、类和对象的创建、集合操作、模式匹配的使用,甚至是Actor系统的简单实现。通过研究这些源代码,你可以更好地理解和掌握Scala语言的核心概念。 总的来说,Scala是...

    Scala考试题1

    4. **case class 和 class 类的区别**: - `case class` 提供了自动的 equals, hashCode, copy, toString 等方法,通常用于数据传输对象(DTO)。 - `class` 没有这些便利,需要手动实现上述功能。 5. **unapply ...

    最好的scala学习 课件

    此外,你还将了解Scala的模式匹配和异常处理机制,这些都是Scala编程的基础。 "Scala进阶之路-part02-集合.pdf"将带你深入了解Scala的集合库,它是Scala语言的一大亮点。这部分会讲解如何使用List、Set、Map等集合...

    scala学习笔记整理

    8. **模式匹配**:Scala的模式匹配不仅限于枚举类型,还可以用于解构类和集合,以及在case类和case对象上使用。这是一种强大的代码简化和错误检测工具。 9. **DSL(Domain Specific Language)**:Scala的语法特性...

Global site tag (gtag.js) - Google Analytics