Scala入门到精通——第十五节 Case Class与模式匹配(二)
本節(jié)主要內(nèi)容
1. 模式的類型
1 常量模式
object ConstantPattern{def main(args: Array[String]): Unit = {//注意,下面定義的是一個函數(shù)//函數(shù)的返回值利用的是模式匹配后的結(jié)果作為其返回值//還需要注意的是函數(shù)定義在main方法中//也即scala語言可以在一個函數(shù)中定義另外一個函數(shù)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",則函數(shù)的返回結(jié)果就是"xxx"case y => y} println(patternShow("xxx"))} }3 構(gòu)造器模式
//構(gòu)造器模式必須將類定義為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這樣的序列集合進行模式匹配
5 元組模式
//匹配某個元組內(nèi)容 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 類型模式
//匹配傳入?yún)?shù)的類型 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))} }上述代碼如果不用模式匹配的話,要實現(xiàn)相同的功能,可以通過下列代碼實現(xiàn):
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)//與@符號,如果后面的模式匹配成功,則將//整體匹配結(jié)果作為返回case List(_,e@List(_,_,_)) => ecase _ => Nil}println(variableBindingPattern(t))} } //編譯執(zhí)行后的輸出結(jié)果為 List(2, 3, 4)- 1
2. for控制結(jié)構(gòu)中的模式匹配
object PatternInForLoop {def main(args: Array[String]): Unit = {val m=Map("china"->"beijing","dwarf japan"->"tokyo","Aerican"->"DC Washington")//利用for循環(huán)對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類型模式匹配
在前面的課程內(nèi)容中,我們曾經(jīng)提到過Option類型,Option類型有兩個子類,分別是Some和None(單例對象),本小節(jié)將從模式匹配的角度對Option類進行重新思考。
下面給出的是Option類在Scala語言中的類層次結(jié)構(gòu):
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")) } //輸出結(jié)果為: //None //-1前面我們看到:None是一個case object,它同Some一樣都extends Option類,只不過Some是case class,對于case class我們已經(jīng)很熟悉了,那case object它又是怎么樣的呢?假設我們定義了以下類:
//下面的類主要用于模擬Option,Some,None三個類或?qū)ο笾g的關系 sealed abstract class A case class B(name:String,age:Int) extends A case object CaseObject extends A{}上述代碼編譯后,生成的字節(jié)碼文件如下:
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單從編譯后生成的類來看,它們之間似乎實現(xiàn)方式都一樣,那到底是什么樣的呢?
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對應的字節(jié)碼文件反編譯后如下:
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對應的反編譯后的內(nèi)容:
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不需要創(chuàng)建對象及進行內(nèi)容提取,從這個角度講,它被定義為case object是十分合理的。
總結(jié)
以上是生活随笔為你收集整理的Scala入门到精通——第十五节 Case Class与模式匹配(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scala入门到精通——第十四节 Cas
- 下一篇: Scala入门到精通——第十六节 泛型与