Scala入门到精通——第十五节 Case Class与模式匹配(二)
本节主要内容
- 模式匹配的类型
- for控制结构中的模式匹配
- option类型模式匹配
1. 模式的类型
1 常量模式
object ConstantPattern{def main(args: Array[String]): Unit = {//注意,下面定义的是一个函数//函数的返回值利用的是模式匹配后的结果作为其返回值//还需要注意的是函数定义在main方法中//也即scala语言可以在一个函数中定义另外一个函数def patternShow(x:Any)=x match {case 5 => "five"case true=>"true"case "test"=>"String"case null=>"null"case Nil=>"empty list"case _ =>"Other constant"} println(patternShow(5))}
}
2 变量模式
object VariablePattern{def main(args: Array[String]): Unit = {def patternShow(x:Any)=x match {case 5 => "five"//所有不是值为5的都会匹配变量y//例如"xxx",则函数的返回结果就是"xxx"case y => y} println(patternShow("xxx"))}
}
3 构造器模式
//构造器模式必须将类定义为case class
case class Person(name:String,age:Int)
object ConstructorPattern {def main(args: Array[String]): Unit = {val p=new Person("摇摆少年梦",27)def constructorPattern(p:Person)=p match {case Person(name,age) => "Person"case _ => "Other"}}
}
- 1
4 序列(Sequence)模式
序列模式指的是像Array、List这样的序列集合进行模式匹配
object SequencePattern {def main(args: Array[String]): Unit = {val p=List("spark","hive","SparkSQL")def sequencePattern(p:List[String])=p match {//只需要匹配第二个元素case List(_,second,_*) => secondcase _ => "Other"}println(sequencePattern(p))}
}
5 元组模式
//匹配某个元组内容
object TuplePattern {def main(args: Array[String]): Unit = {val t=("spark","hive","SparkSQL")def tuplePattern(t:Any)=t match {case (one,_,_) => onecase _ => "Other"}println(tuplePattern(t))}
}
- 1
6 类型模式
//匹配传入参数的类型
object TypePattern {def main(args: Array[String]): Unit = {def tuplePattern(t:Any)=t match {case t:String=> "String"case t:Int => "Integer"case t:Double=>"Double"}println(tuplePattern(5.0))}
}
上述代码如果不用模式匹配的话,要实现相同的功能,可以通过下列代码实现:
def tuplePattern2(t:Any)={if(t.isInstanceOf[String]) "String"else if(t.isInstanceOf[Int]) "Int"else if(t.isInstanceOf[Double]) "Double"else if(t.isInstanceOf[Map[_,_]]) "MAP"}
7 变量绑定模式
object VariableBindingPattern {def main(args: Array[String]): Unit = {var t=List(List(1,2,3),List(2,3,4)) def variableBindingPattern(t:Any)= t match {//变量绑定,采用变量名(这里是e)//与@符号,如果后面的模式匹配成功,则将//整体匹配结果作为返回case List(_,e@List(_,_,_)) => ecase _ => Nil}println(variableBindingPattern(t))}
}
//编译执行后的输出结果为 List(2, 3, 4)
- 1
2. for控制结构中的模式匹配
object PatternInForLoop {def main(args: Array[String]): Unit = {val m=Map("china"->"beijing","dwarf japan"->"tokyo","Aerican"->"DC Washington")//利用for循环对Map进行模式匹配输出,for((nation,capital)<-m)println(nation+": " +capital)}
}
正则表达式中的模式匹配:
object RegexMatch {def main(args: Array[String]): Unit = {
val ipRegex="(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)".rfor(ipRegex(one,two,three,four) <- ipRegex.findAllIn("192.168.1.1")){println("IP子段1:"+one)println("IP子段2:"+two)println("IP子段3:"+three)println("IP子段4:"+four)}}
}
3. Option类型模式匹配
在前面的课程内容中,我们曾经提到过Option类型,Option类型有两个子类,分别是Some和None(单例对象),本小节将从模式匹配的角度对Option类进行重新思考。
下面给出的是Option类在Scala语言中的类层次结构:
Option类其实是一个sealed class
//Option类的部分源码
sealed abstract class Option[+A] extends Product with Serializable {self =>/** Returns true if the option is $none, false otherwise.*/def isEmpty: Boolean/** Returns true if the option is an instance of $some, false otherwise.*/def isDefined: Boolean = !isEmpty
下面给出的分别是Some及None的源码:
/** Class `Some[A]` represents existing values of type* `A`.** @author Martin Odersky* @version 1.0, 16/07/2003*/
final case class Some[+A](x: A) extends Option[A] {def isEmpty = falsedef get = x
}/** This case object represents non-existent values.** @author Martin Odersky* @version 1.0, 16/07/2003*/
case object None extends Option[Nothing] {def isEmpty = truedef get = throw new NoSuchElementException("None.get")
}
下面的代码演示了其如何应用到模式匹配中:
object OptionDemo extends App{val m=Map("hive"->2,"spark"->3,"Spark MLlib"->4)def mapPattern(t:String)=m.get(t) match {case Some(x) => println(x);xcase None => println("None");-1}println(mapPattern("Hive"))
}
//输出结果为:
//None
//-1
前面我们看到:None是一个case object,它同Some一样都extends Option类,只不过Some是case class,对于case class我们已经很熟悉了,那case object它又是怎么样的呢?假设我们定义了以下类:
//下面的类主要用于模拟Option,Some,None三个类或对象之间的关系
sealed abstract class A
case class B(name:String,age:Int) extends A
case object CaseObject extends A{}
上述代码编译后,生成的字节码文件如下:
D:\ScalaWorkspace\ScalaChapter15\bin\cn\scala\xtwy 的目录2015/08/01 21:26 <DIR> .
2015/08/01 21:26 <DIR> ..
2015/08/01 21:26 515 A.class
2015/08/01 21:26 1,809 B$.class
2015/08/01 21:26 4,320 B.class
2015/08/01 21:26 1,722 CaseObject$.class
2015/08/01 21:26 1,490 CaseObject.class
单从编译后生成的类来看,它们之间似乎实现方式都一样,那到底是什么样的呢?
class A的反编译后的代码如下:
D:\ScalaWorkspace\ScalaChapter15\bin\cn\scala\xtwy>javap -private A.class
Compiled from "CaseObject.scala"
public abstract class cn.scala.xtwy.A {public cn.scala.xtwy.A();
}
case class B对应的字节码文件反编译后如下:
D:\ScalaWorkspace\ScalaChapter15\bin\cn\scala\xtwy>javap -private B.class
Compiled from "CaseObject.scala"
public class cn.scala.xtwy.B extends cn.scala.xtwy.A implements scala.Product,sc
ala.Serializable {private final java.lang.String name;private final int age;public static scala.Function1<scala.Tuple2<java.lang.String, java.lang.Object>
, cn.scala.xtwy.B> tupled();public static scala.Function1<java.lang.String, scala.Function1<java.lang.Obje
ct, cn.scala.xtwy.B>> curried();public java.lang.String name();public int age();public cn.scala.xtwy.B copy(java.lang.String, int);public java.lang.String copy$default$1();public int copy$default$2();public java.lang.String productPrefix();public int productArity();public java.lang.Object productElement(int);public scala.collection.Iterator<java.lang.Object> productIterator();public boolean canEqual(java.lang.Object);public int hashCode();public java.lang.String toString();public boolean equals(java.lang.Object);public cn.scala.xtwy.B(java.lang.String, int);
}//自动生成的伴生对像类
public final class cn.scala.xtwy.B$ extends scala.runtime.AbstractFunction2<java
.lang.String, java.lang.Object, cn.scala.xtwy.B> implements scala.Serializable {public static final cn.scala.xtwy.B$ MODULE$;public static {};public final java.lang.String toString();public cn.scala.xtwy.B apply(java.lang.String, int);public scala.Option<scala.Tuple2<java.lang.String, java.lang.Object>> unapply(
cn.scala.xtwy.B);private java.lang.Object readResolve();public java.lang.Object apply(java.lang.Object, java.lang.Object);private cn.scala.xtwy.B$();
}
case object CaseObject对应的反编译后的内容:
D:\ScalaWorkspace\ScalaChapter15\bin\cn\scala\xtwy>javap -private CaseObject.cla
ss
Compiled from "CaseObject.scala"
public final class cn.scala.xtwy.CaseObject {public static java.lang.String toString();public static int hashCode();public static boolean canEqual(java.lang.Object);public static scala.collection.Iterator<java.lang.Object> productIterator();public static java.lang.Object productElement(int);public static int productArity();public static java.lang.String productPrefix();
}D:\ScalaWorkspace\ScalaChapter15\bin\cn\scala\xtwy>javap -private CaseObject$.cl
ass
Compiled from "CaseObject.scala"
public final class cn.scala.xtwy.CaseObject$ extends cn.scala.xtwy.A implements
scala.Product,scala.Serializable {public static final cn.scala.xtwy.CaseObject$ MODULE$;public static {};public java.lang.String productPrefix();public int productArity();public java.lang.Object productElement(int);public scala.collection.Iterator<java.lang.Object> productIterator();public boolean canEqual(java.lang.Object);public int hashCode();public java.lang.String toString();private java.lang.Object readResolve();private cn.scala.xtwy.CaseObject$();
}
对比上述代码不难看出,case object与case class所不同的是,case object对应反编译后的CaseObject$.class中不存在apply、unapply方法,这是因为None不需要创建对象及进行内容提取,从这个角度讲,它被定义为case object是十分合理的。
Scala入门到精通——第十五节 Case Class与模式匹配(二)相关推荐
- Scala入门到精通——第十四节 Case Class与模式匹配(一)
本节主要内容 模式匹配入门 Case Class简介 Case Class进阶 1. 模式匹配入门 在Java语言中存在switch语句,例如: //下面的代码演示了java中switch语句的使用 ...
- Scala入门到精通——第二十五节 提取器(Extractor)
本节主要内容 apply与unapply方法 零变量或变量的模式匹配 提取器与序列模式 scala中的占位符使用总结 1. apply与unapply方法 apply方法我们已经非常熟悉了,它帮助我们 ...
- Scala入门到精通——第二十六节 Scala并发编程基础
本节主要内容 Scala并发编程简介 Scala Actor并发编程模型 react模型 Actor的几种状态 Actor深入使用解析 1. Scala并发编程简介 2003 年,Herb Sutte ...
- Scala入门到精通——第二十九节 Scala数据库编程
本节主要内容 Scala Mavenproject的创建 Scala JDBC方式訪问MySQL Slick简单介绍 Slick数据库编程实战 SQL与Slick相互转换 本课程在多数内容是在官方教程 ...
- Scala入门到精通——第二十四节 高级类型 (三)
本节主要内容 Type Specialization Manifest.TypeTag.ClassTag Scala类型系统总结 在Scala中,类(class)与类型(type)是两个不一样的概念. ...
- Scala入门到精通——第十九节 隐式转换与隐式参数(二)
本节主要内容 隐式参数中的隐式转换 函数中隐式参数使用概要 隐式转换问题梳理 1. 隐式参数中的隐式转换 前一讲中,我们提到函数中如果存在隐式参数,在使用该函数的时候如果不给定对应的参数,则编译器会自 ...
- Scala入门到精通——第十六节 泛型与注解
本节主要内容 泛型(Generic Type)简介 注解(Annotation)简介 注解常用场景 1. 泛型(Generic Type)简介 泛型用于指定方法或类可以接受任意类型参数,参数在实际使用 ...
- Excel数据分析从入门到精通(十五)数据透视表之动态仪表盘
Excel数据分析从入门到精通(十五)数据透视表之动态仪表盘 1.绘制销售额汇总情况 2.绘制种类销售额情况+种类销售额占比 种类销售额情况 种类销售占比 3.绘制地区销售额情况和地区销售额占比 地区 ...
- Excel数据分析从入门到精通(十五)数据透视表基础
Excel数据分析从入门到精通(十五)数据透视表 1.Excel透视表前言 2.Excel透视表的创建 3.Excel透视表的组成 4.Excel透视表的十大技巧 ①如何创建汇总行 ②如何展示百分比 ...
最新文章
- [BZOJ1572][Usaco2009 Open]工作安排Job
- 利用java多线程向MongoDB中批量插入静态文件
- Linux scp常用命令
- python打完代码怎么运行-Python的代码是如何去进行运行的?
- ubuntu16.04安装UR3/UR5/UR10机械臂的ROS驱动并实现gazebo下Moveit运动规划仿真以及真实UR3机械臂的运动控制(3)
- win phone 获取并且处理回车键事件
- Open3d之文件IO
- Prototype使用$R()函数
- css table中设置tr行间距
- 第三届泰迪杯全国大学生数据挖掘竞赛通知
- Arduino + W5100调试笔记(1)
- MOOC 哈工大苏小红C语言 第七周练兵区——编程题
- 数据处理常用方法(python)
- 搬砖的成长之路——VMWare网络原理
- 多台linux服务器ssh相互无密码访问
- CatBoost参数解释
- 移动桌面到其他盘:C盘不够用,如何【修改桌面存储位置】
- 《资本论》读书笔记(2)第二卷第一章:资本形态变化及其循环
- 对一阶二阶低通滤波器推导,并用IMU数据验证算法效果
- C++ 实现1011 A+B 和 C
热门文章
- (干货满满!)session和cookie作用原理,区别(史上最详细)
- yy直播没声音html,驱动技巧:解决YY语音中麦克风无声或者有噪音的问题
- 如何统一集体的所有人的yum环境(以阿里云为例)
- kotlin读取sd卡里的文件_Kotlin 读取文件
- unity3d 不规则外发光描边_Shader案例之内发光和边缘泛光效果
- java threadstatus_Thread之一:线程生命周期及六种状态
- php正则相对地址,php – 正则表达式将相对URL更改为绝对值
- php父类继承子类_php有多态吗 多态都有什么好处?理解好多态往往能事半功倍...
- mongodb启动成功连不上_MySQL数据导入到MongoDb教程
- php在html中生成option,php-如何为使用laravel表单生成器创建的select标签的选项指定HTML属性?...