Scala模式匹配--样例类--密封样例类--偏函数

模式匹配

等价于java的switch caseval c = '+'c match{case '+' => println(111)case '-' => println(222)case _ => println(0)}

匹配常量

//匹配值,没有break
val x :Char= '+'
//万一xx存在这种可能case '-'=>"100" case _=>0.0F
//val xx :Int=x match{
val xx :Any=x match{ //Any所有类的超类case '+'=>100case '-'=>"100"case _=>0.0F
}

守卫条件

val x = c match{case '+' => 1case '-' => -1case _ if Character.isDigit(c) => 'N'//case _if x.isDigit=>0.0F 它如果是数字case _ => 'X'}
val x :Char='9'
val xx:Any=x match{case '+'=>100case '-'=>"100"case _if x.isDigit=>println("is number")  //if x.isDigit这里就是守卫条件case _=>println(x)
}
//守卫可以是任何Boolean条件。
注意模式总是从上往下进行匹配。如果带守卫的这个模式不能匹配,则捕获所有的模式(case_)会被用来尝试进行匹配。

使用变量:如果case关键字后面跟着一个变量名,那么匹配的表达是会被赋值给那个变量。

val str = "hello"str(0) match{case '+' => println(1)case '-' => println(2)case ch => println(ch)}

常量问题,大写会识别成常量,小写是变量,如果让小写也是常量,使用``标出

val str = "hello"val ch = 'h'str(0) match{case '+' => println(1)case '-' => println(2)case `ch` => println(`ch`)}

类型匹配

val x:Any = "abc"x match{case a:Int => println(1)case a:String => println(2)case a:Float => println(3)case _ => println(0)}

匹配数组

val arr=Array(0)        //  100 is Int
val arr=Array(0,1)      //2=>x:0
val arr=Array(0,1,2,3) //default
arr match{//精确匹配case Array(0)=>println(1)  //匹配两个元素case Array(x,y)=>println(2+"=>x: "+x)//匹配0为首个元素case Array(0,_*)=>println(3)case _=>println("default")
}val arr = Array[Int](1,2,3)arr match{//case Array(0) => println(1)         //精确匹配(0)case Array(x,y) => println(2)         //匹配2个元素case Array(0,_*) => println(3)        //匹配0开始case _ => println(4)                  //}
总结:第一个模式匹配包含0的数组。第二个模式匹配任何带有两个元素的数组,并且将这两个元素分别绑定到变量x和y中。第三个表达式匹配任何以零开始的数组。

匹配集合(List)

val list = 0::1::2::Nillist match{case 0::Nil => println(1)             //0case x::y::Nil => println(2)          //x,ycase 0::tail => println(3)                   //0,...case _ => println(4)}val list=1::2::Nil      //2 =>x: 1
val list=0::1::2::Nil   //List(1,2)
list match{//精确匹配case 0::Nil=>println(1)//匹配两个元素case x::y::Nil=>println(2+"=>x: "+x)//匹配0为首个元素case 0::tail=>println(tail)case _=>println("default")
}

匹配元组

val t = (1,2)t match{case (0,_) => println(1)case (y,0) => println(2)case _ => println(3)}
val t=(0,1) //100
val t=(1,0) //200  必须符合case里面的条件才行
t match{case(0,_)=>println("100")case(x,0)=>println("200")case _ =>println("default")
}val(x,y)=(1,2)
同时把x定义为1,把y定义为2.这对于使用那些返回对偶的函数而言很有用
val (q,r)=BigInt(10)/%3
/%方法返回包含商和余数的对偶,而这两个值分别被变量q和r捕获到。

提取器unapply / unapplySeq

val arr = Array(1,2,3)arr match{case Array(x,y,z)=> printf("x=%d,y=%d,z=%d" , x , y  ,z)case _ => println("0")}
scala> val t=<1,2>
t:<Int,Int>=<1,2>
scala> val<x,y>=t  //可以同时把t给抽出来
x:Int=1
y:Int=2
scala> val<x,y>=t//反向抽取
//如果元素很多,可以用t给抽出来
scala>val t=<1,"tom",12,"henan">
t:<Int,String,Int,String>=<1,tom,12,henan>
scala>val<id,name,age,addr>=t
id:Int=1
name:String=tom
age:Int=12
addr:String=henan

多个变量声明模式

val (x,y,z) = (1,2,3)x = 1y = 2z = 3
//模式匹配的变量声明模式
val t=(1,"tom",12,"henan")  //这个就是元组
val (id,name,age,addr)=t
println(id)
[源码解析]
Tuple4  extends(继承)Product4
object Product4{def unapply[T1,T2,T3,T4]  (x:Product4[T1,T2,T3,T4]):Option[Product4[T1,T2,T3,T4]]=Some(x)option类型(Some(类) , None(单例对象))
}
------------------
//同时提取商和余数
val (a,b)=BigInt(5) /% 3
val arr=Array(1,2,3,4)
val Array(x,y,_*)=arr  //for循环的map迭代
println(x+","+y)//1,2
val map=Map(1->"tom1",2->"tom2")
//相当于反向抽取(常见的形式)
for((k,y)<-map ){println(k+"="+v)
}

抽取前两个元素依次赋值

val Array(x,y,_*) = Array(1,2,3,4,5)val map = Map(1->"tom1" , 2->"tom2",3->"tom3")for((k,_) <- map) println(k)for(t <- map) println(t._1)
//模式匹配的变量声明模式

样例类

.样例类是一种特殊的类,它们经过优化以被用于模式匹配。内置实现了很多便捷的方法,比如apply/unapply/serilizable/compare/toString

abstact classAmount  //一个抽象类
//定义了两个样例类
case class Dollar(value:Double)extends Amount
case class Currency(value: Double,unit: String)extends Amount  //样例类必须要有属性
//通过普通类定义一个子类,它和样例类有啥区别
object CaseClassDemo{def main(args:Array[String]):Unit={abstract class Amount//定义样例类  //sealed(密封),样例子类和样例父类如果不加sealed是可以定义在不同的scala文件里的 如果加了sealed就必须跟它的父类定义在同一个Scala文件中//case class Dollar(cnt:Int)extends Amount样例子类,sealed的优点是:在一个scala文件中可以找到它所有的sealed子类,就不会存在在其它的包里面或文件夹里面。sealed case class Dollar(cnt:Int)extends Amountcase class RenmiYuan(cnt:Int)extends Amount//定义一个样例对象case object NoMoney extends Amount//可以实例化对象(快速构建对象)//applyval d1=Dollar(10)//applyval r1=RenmiYuan(100)//打印      --因为里面已经重新了toString方法println(d1)  //Dollar(10)println(r1)  //RenmiYuan(100)//快速抽出里面的属性//unapplyval Dollar(x)=d1  //10//unapplyval RenmiYuan(y)=r1 //100println(x)//Serializable(scala)继承java里面的,就是java里面的串行化接口实现package scalatrait Serializable extends Any with java.io.Serializable-------------样例对象模式匹配----------------- //给样例对象变量,是否可以模式匹配,这里用到的都是unapply反解析val m=Dollar(300)    //300美元 val m:Amount=RenmiYuan(300)//300人民币val m:Amount=NoMoney  //NoMoney本来就是样例对象//模式匹配,判断它是美元还是人民币//对样例实例进行模式匹配m match{case Dollar(x)=>println(x+"美元")case RenmiYuan(y)=>println(y+"人民币")case NoMoney=>println("没钱")}}
}

密封样例类

必须将样例子类和父类定义在一个scala文件中。
方便在一个scala文件中找到所有的子类。不允许在其他地方定义
子类。和匹配模式配合使用,非常方便。
//sealed 密封
sealed abstract class Dog
case class Jing8(var name:String) extends Dog
case class Shapi(var name:String) extends Dog
[典型的密封样例类源码]
//Option密封抽象类
sealed abstract class Option[+A]extends Product with Serializable
它的两个子类 None  Some
//None子对象(样例对象)
case object None extends Option[Nothing]{def isEmpty=truedef get=throw new NoSuchElementException("None.get")
}
//Some(样例类)
final case class Some[+A](x: A)extends Option[A]{def isEmpty=falsedef get=x
}

偏函数(PartialFunction)

被包在花括号内的一组case语句是一个偏函数---一个并非对所有输入值都有定义的函数。它是PartialFunction[A,B]类的一个实例。(A是参数类型,B是返回类型。)该类有两个方法:apply方法从匹配到模式技术函数值,而isDefinedAt方法在输入至少匹配其中一个模式时返回true.

模式匹配有一个缺点就是代码需要重用,假如很多地方需要用到模式匹配。就需要反复的写这些东西,完全可以{}包起来的一组case给它封装成一个对象,这个对象就叫做偏函数。偏函数还有一种情况就是,它没有完全把所有的情况罗列完整。它只是一部分,或者是若干情况。
偏函数的作用:偏函数就是对模式匹配代码进行重用,以备于在其它的地方还可以利用这段代码执行模式匹配的动作。
//偏函数,对模式匹配的封装,重用模式匹配的代码
object PartialFunctionDemo{def main(args:Array[String]):Unit={val ch:Char='+'val r=ch match{case '+'=>1case '-'=>-1case _=>0}println(r) //1//定义一个偏函数对象(类),代码就是把case放进去val f:PartialFunction[Char,Int]={case '+'=>1case '-'=>-1case _=>0}//isDefinedAt是否定义了这种情况,它是判断是否有没有定义这种情况的处理println(f.isDefinedAt('+')) //1println(f.isDefinedAt('9')) //true  如果把//case _=>0注释点就 false//调用这个println(f.apply('+')) //1//可以简写println(f('-'))   //-1println(f('9'))//注释掉 case _=>0,则抛异常(MatchError)没有定义这个数}
}

转载于:https://www.cnblogs.com/SteveDZC/p/9765746.html

Scala模式匹配--样例类--密封样例类--偏函数相关推荐

  1. Scala学习笔记(三)——面向对象、类、抽象类、伴生、内部类、样例类、枚举、泛型类、类型边界、型变、特质、动态混入、包

    Scala面向对象 Scala面向对象 一.基本概念 1.类的概念 2.类成员访问修饰符 二.类 1.类的定义 2.类的继承 3.抽象类 4.单例对象 5.伴生 6.内部类 7.样例类 8.枚举 9. ...

  2. 《JAVA练习题目9》 创建一个Person类和一个Family类。(这次的OJ实在写的没有状态,被样例搞崩了,这次代码还有好多代码复制等一系列不良现象,就是为了过OJ写的。。大家凑活看一下吧)

    题目内容: 创建一个Person类和一个Family类.其中, Person类包含编号id(整型).名字name(字符串).性别gender(字符串)三个属性,和一个初始化对象所有属性的有参构造方法, ...

  3. 磁共振神经根水成像_磁共振神经根水成像鉴别类肿瘤样椎间盘突出症与神经鞘瘤2例...

    脱垂游离型椎间盘突出症是指突出的椎间盘组织脱离纤维环裂孔,在椎管内游离移动一定距离引起的相应神经根压迫症状.磁共振成像(MRI)是诊断脊柱病变的首选检查和金标准.在极少数情况下游离的椎间盘组织MRI表 ...

  4. ACMNO.13求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字。 输入 n 输出 和 样例输入 5 样例输出 153

    题目描述 求Sn=1!+2!+3!+4!+5!+-+n!之值,其中n是一个数字. 输入 n 输出 和 样例输入 5 样例输出 153 来源/分类 C语言 题目截图: 思路: 首先要想到使用两个for循 ...

  5. S7-200Smart 恒压供水程序样例+485通讯样例 + 触 摸屏样例子

    S7-200Smart 恒压供水程序样例+485通讯样例 + 触 摸屏样例子. 1.此程序样例为一拖二恒压供水样例,采用S7-200Smart PLC和smart 700触摸屏人机与abb变频器485 ...

  6. S7-200Smart 恒压供水程序样例+485通讯样例 + 触摸屏样例子

    S7-200Smart 恒压供水程序样例+485通讯样例 + 触摸屏样例子. 1.此程序样例为一拖二恒压供水样例,采用S7-200Smart PLC和smart 700触摸屏人机与abb变频器485通 ...

  7. scala什么是单例对象_Scala单例和伴侣对象

    scala什么是单例对象 Scala中的单例对象 (Singleton objects in Scala) Scala being an object-oriented programming lan ...

  8. python面试题~反射,元类,单例

    1 什么是反射?以及应用场景? test.py def f1():print('f1') def f2():print('f2') def f3():print('f3') def f4():prin ...

  9. python元类单例_python面向对象和元类的理解

    1 python类对象与实例对象 python中一切皆对象(广义上的对象),类也不例外,我们可以称类为类对象.python中内建函数type()可以返回对象的类型,例如type(int)会得到返回值, ...

最新文章

  1. 企业防火墙之iptables
  2. java笔试之简单密码
  3. 8.1 matlab图形窗口与坐标轴(图形对象的句柄和属性、坐标轴的操作、图形窗口的操作)
  4. CDH预警配置QQ邮箱
  5. Redis 会遇到的「坑」,你踩过几个?
  6. Android程序打开和关闭输入法
  7. Js中RegExp对象
  8. UML图各类符号含义
  9. 基于CAS4.0.0的单点登陆
  10. Android APP旋转屏幕
  11. 计算机专业术语linklist,常见的计算机专业词汇 .
  12. Android 基础篇之环境配置
  13. xp系统中如何修复浏览器打不开的问题
  14. 关于心跳包的实现手法
  15. 华为 GT Runner测评:为跑者而生的专业跑表
  16. HC-05蓝牙模块初始化及测试
  17. 排球制作html,3D教程-排球的制作
  18. 大学公开课网站视频课程转码加密方案
  19. php开发工程师学费,青岛PHPWEB开发工程师班
  20. 秀刻Showlike+

热门文章

  1. Aspects深度解析-iOS面向切面编程
  2. 【往届期末试卷】毛概期末试卷
  3. A comparative review of tone-mapping algorithms for high dynamic range video(高动态范围视频色调映射算法的比较研究)(二)
  4. China Operating System 电脑操作系统 2016全球互联网排名
  5. 小陈学JS 数组转换为分割字符串
  6. 奇幻RPG(物品锻造 与 Decorator模式)
  7. 浅读《简约之美-软件设计之道》
  8. 网站搭建超详细教程(零基础)
  9. 为什么银行家舍入是合理的?
  10. 《程序员2010精华本》china-pub预定中