scala模式匹配与样例类
样本类:添加了case的类便是样本类。这种修饰符可以让Scala编译器自动为这个类添加一些语法上的便捷设定。如下:
1.添加与类名一致的工厂方法。也就是说,可以写成Var("x")来构造Var对象。
2.样本类参数列表中的所有参数隐式获得了val前缀,因此它被当作字段维护。
3.编译器为这个类添加了方法toString,hashCode和equals等方法。
模式匹配:
match对应Java里的switch,但是写在选择器表达式之后。即: 选择器 match {备选项}。
一个模式匹配包含了一系列备选项,每个都开始于关键字case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
match表达式通过以代码编写的先后次序尝试每个模式来完成计算。类似于UnOp("-" , UnOp("-" , e))这种形式的,是构造器模式匹配。
match与switch的比较:匹配表达式可以被看作Java风格Switch的泛化。但有三点不同:
- match是Scala的表达式,始终以值作为结果;
- Scala的备选项表达式永远不会“掉到”下一个case;
- 如果没有模式匹配,MatchError异常会被抛出。这意味着必须始终确信所有的情况都考虑到了,或者至少添加一个默认情况什么都不做。如 case _ =>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
代码示例:
- /*
- desc:模拟控制数学表达式的库。
- 由变量、数字、一元及二元操作符组成的数学表达式。
- jb,完全照书上的来说。
- */
- object simpleBegin {
- def main(args: Array[String]): Unit = {
- //--x
- println(simplifyTop(UnOp("-", UnOp("-", Var("x")))))
- //x+0
- println(simplifyTop(BinOp("+", Var("x"), Number(0))))
- //x*1
- println(simplifyTop(BinOp("*", Var("x"), Number(1))))
- //abs abs x
- println(simplifyTop(UnOp("abs", UnOp("abs", Var("x")))))
- }
- //层级包括一个抽象基类Expr和四个子类,每个代表一种表达式。所有的五个类都没有结构体。
- //class C 和 class C {} 一个意思。
- 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
- //“e“是什么意思????变量模式!
- //tips: case BinOp("*", e, Number(1)) => e 可以写成: case BinOp(a, e, b) => e !!!!!!!!!!!!!
- def simplifyTop(expr: Expr): Expr = expr match{
- case UnOp("-", UnOp("-", e)) => e
- case BinOp("+", e, Number(0)) => e
- case BinOp("*", e, Number(1)) => e
- //变量绑定,规则:变量 @ 模式,此时“变量”就代表了后面的“模式”:Unop("abs", _)
- case UnOp("abs", x @ UnOp("abs", _)) => x
- }
- }
-------------------------------------------------------------------------------------------------------------------------------------------------------------
输出结果:
Var(x)
Var(x)
Var(x)
UnOp(abs,Var(x))
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
模式的种类
通配模式: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里类型测试和转换的代码很冗长,因为不建议这么做。
- case BinOp("+" , x , x ) => BinOp("*" , x , Number(2))
模式守卫:模式变量仅允许在模式中出现一次。如:
这种写法就会出错。可以改成: case BinOp("+" , x , y ) if x == y => BinOp("*" , x , Number(2))
模式守卫接在模式之后,开始于if。守卫可以是任意的引用模式中变量的布尔表达式。如果存在模式守卫,那么只有在守卫返回true的时候匹配才成功。
scala模式匹配与样例类的更多相关文章
- Scala模式匹配和样例类
Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等.并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配. 1.字符匹配 def mai ...
- Scala基础:模式匹配和样例类
模式匹配 package com.zy.scala import scala.util.Random /** * 模式匹配 */ object CaseDemo { def main(args: Ar ...
- 学好Spark/Kafka必须要掌握的Scala技术点(二)类、单例/伴生对象、继承和trait,模式匹配、样例类(case class)
3. 类.对象.继承和trait 3.1 类 3.1.1 类的定义 Scala中,可以在类中定义类.以在函数中定义函数.可以在类中定义object:可以在函数中定义类,类成员的缺省访问级别是:publ ...
- 大数据学习day16------第三阶段-----scala04--------1. 模式匹配和样例类 2 Akka通信框架
1. 模式匹配和样例类 Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等.并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配 1.1 模式匹 ...
- 【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型
一.前述 Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大. 模式匹配机制相当于java中的switch-case. 使用了case关键字的类定义就是样例类(case ...
- Scala学习十四——模式匹配和样例类
一.本章要点 match表达式是更好的switch,不会有意外调入下一个分支 如果没有模式能够匹配,会抛出MatchError,可以用case _模式避免 模式可以包含一个随意定义的条件,称做守卫 你 ...
- Scala集合库、模式匹配和样例类
package com.yz8 import org.junit.Test class test { @Test def test: Unit = { val ints = List(1,5,7,6, ...
- Scala-Unit6-final/type关键字、样例类&样例对象
一.关键字 1.final关键字 用final修饰的类:不能被继承 用final修饰的方法:不能被重写 注意:(1)在Scala中变量不需要用final修饰,因为val与var已经限制了变量是否可变 ...
- Scala--模式匹配和样例类
模式匹配应用场景:switch语句,类型查询,析构,样例类 一.更好的switch val ch :Char = '+' val sign = ch match{ case '+' => 1 c ...
随机推荐
- 关于MTK平台SIM-ME Lock的配置方案
针对一些运营商的锁网需求,MTK平台已经对其有很好的支持.绝大多数的海外需求可以通过直接配置相关文件来完成.这里简单描述一下配置方法,不做原理分析. 相关数据结构分析: Modem中与SML锁网配置相 ...
- PHP下利用PHPMailer配合QQ邮箱下的域名邮箱发送邮件
作 为PHP入门开发者,常常有这种述求:自己的网站中需要添加一个使用自己的域名作为发件人邮件地址的自动发送邮件的方法,用于诸如给用户发送验证码.通知 信息等.比如:我的某个用户注册模块,需要使用reg ...
- vmware 安装提示the msi failed
原因是卸载不干净,使用批处理bat文件卸载,然后重启即可. VMware workstation 10.0序列号:MA491-6NL5Q-AZAM0-ZH0N2-AAJ5A 百度云文件:http:// ...
- 【01-14】java ThreadLocal工具类
自定义ThreadLocal package concurrent; import java.util.HashMap; import java.util.Map; /** * @author alo ...
- VC MFC工具栏(CToolBar)控件
一.工具栏 工具栏控件在控件面板里没有对应的选项(图标),但有一个工具栏控件类CToolBar,所以我们如果要创建一个工具栏控件并显示在窗口里的话,只能用代码来完成,事实上任何一种控件,都可以用代码创 ...
- 如何迅速成为Java高手[转]
很多网友问我学习Java有没有什么捷径,我说“无他,唯手熟尔”.但是我却很愿意将自己学习的一些经验写出来,以便后来者少走弯路,帮助别人是最大的快乐嘛! 要想学好Java,首先要知道Java的大致分类. ...
- Tomcat 7优化
1.在bin/catalina.bat文件中加入下面参数,对JVM进行优化,至于这一大驼参数的作用及说明,大家到网上找找,应该有很多的,如:http://www.mzone.cc/article/32 ...
- Hadoop2.6.0 动态增加节点
本文主要从基础准备,添加DataNode和添加NodeManager三个部分详细说明在Hadoop2.6.0环境下,如何动态新增节点到集群中. 基础准备 在基础准备部分,主要是设置hadoop运行的系 ...
- sysbench使用教程【转载】
水晶命匣 2016-08-16 20:02 一.环境描述 此次使用的虚拟机环境如下所示: CPU:双核 2.4GHz 内存:4 GB 硬盘:120 GB IP:192.168.21.129 操作系统: ...
- 更改JFram标题栏图标
方式一: package com.swing.test; import javax.swing.ImageIcon; import javax.swing.JFrame; public class a ...