日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scala入门到精通——第十五节 Case Class与模式匹配(二)

發布時間:2024/1/23 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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与模式匹配(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。