大資料之scala(四) --- 模式匹配,變數宣告模式,樣例類,偏函式,泛型,型變,逆變,隱式轉換,隱式引數
阿新 • • 發佈:2018-11-09
一、模式匹配:當滿足case條件,就終止 ---------------------------------------------------------- 1.更好的switch var x = '9'; x match{ case '+' => println(" +++ ") case '-' => println(" --- ") case _ if Character.isDigit(x) => print("is number!"); //帶守護條件 case _ => println(" *** ") //相當於 case 中的default } 2.匹配型別 val x:Any = '1'; //Any所有型別的超類 x match{ case a:String => println("is String") case b:Int => println("is Int") case _ => println("****") } 3.匹配陣列 val arr = Array(0,2) arr match { case Array(0,1) => println("是陣列0,1") //匹配陣列是否是Array(0,1) case Array(x,y) => println("是兩個元素的陣列") //匹配陣列是否只有2個元素 case Array(0,_*) => println("是以0開始的陣列") //匹配陣列是否以0為第一個元素 case _ => println("***") //default } 二、變數宣告模式 -------------------------------------------- val x = 100 ; // val t = (1,2,3,4) ; //元組 t _1 //訪問元組的第1個元素 t._1 //訪問元組的第1個元素 val (a,b,c, d) = t //解析元組中組員.將元組中的前三個元素賦值給 a,b,c,d 三、樣例類 :主要用於模式匹配 ----------------------------------------------- 1.主要用於模式匹配.內建了apply和unapply方法,實現了序列化等介面。建立物件時不需要使用new. abstract class Dog{} case class Jing8(name:String) extends Dog{} case class Shapi(age:Int) extends Dog{} //新建物件不需要new,直接應用apply方法 scala> val d = Jing8("tom") d: Jing8 = Jing8(tom) //模式匹配 val d:Dog = new Jing8("tom"); d match{ case Jing8(name) => print("是Jing8 : " + name); case Shapi(age) => print("是Shapi : " + age); case _ => print("aishiuihsui"); } 2.密封樣例類 子類和父類必須定義在同一檔案中。父類用sealed宣告 sealed abstract class Dog{} case class Jing8(name:String) extends Dog{} case class Shapi(age:Int) extends Dog{} 四、偏函式 ------------------------------------------------ val f:PartialFunction[Char,Int] = { case '+' => 1 ; case '-' => -1 case _ => 0 } scala> f('+') res214: Int = 1 scala> f('-') res215: Int = -1 scala> f('*') res216: Int = 0 五、泛型 ---------------------------------------------------- 1.泛型類 //定義一個帶有兩個型別引數T和S的類。 class Pair[T,S] (val first:T , val second :S ){ ... } val p = new Pair(42,"String"); // T :Int S :String val p = new Pair[Any,Any](42,"String"); // T :Int S :String 2.泛型函式 def getMiddle[T] (a:Array[T]) = { a(a.length / 2); } scala> getMiddle(Array(1,2,3,4)) res218: Int = 3 3.泛型的界 a.變數型別的限定 //要求2個引數的型別相同 class Pair[T](val first:T , val second :T ) b. <: 上界:要求泛型T必須是指定的型別的子類 //泛型T必須是Dog的子類 def run[T <: Dog](d:T) = println("hello") b. >: 下界:要求泛型T必須是指定的型別的超類 //泛型T必須是Dog的超類 def run[T >: Dog](d:T) = println("hello") c. <% : 要求泛型T必須可以隱式轉換成指定型別 六、型變/逆變 ------------------------------------------------------ 1.型變[+T] class Pair[T] (val first : T, val second : T) def makeFriends(p : Pair[Person]) //函式makeFriends的引數p的型別是Pair[Person] 已知,Student 是 Person的子類, 但是 makeFriends(new Pair[Person]()) 可以 makeFriends(new Pair[Student]()) 不可以 因為雖然Student 是 Person的子類,但是Pair[Person] 和 Pair[Student]沒有關係 如果想Pair[Person] 和 Pair[Student],也具有Student 和 Person一樣的關係,就需要宣告型變 class Pair[+T] (val first : T, val second : T) //+T,表示 pair與T具有相同的繼承關係 2.逆變[-T] -- 型變的反向 如果,class Pair[-T] (val first : T, val second : T) 已知,Student 是 Person的子類, 那麼, Pair[Student] 就是 Pair[Person] 的父類 七、隱式轉換 ---------------------------------------------------------- 1.隱式轉換函式 使用implicit修飾的具有一個引數的函式。把一種型別變換成另外一種型別 //定義隱式轉換函式,當整數和Dog之間可以隱式轉換。Dog相當於整數 //對於int2Dog,是將n:Int的值,賦值給沙皮狗的年齡 implicit def int2Dog(n:Int) = Shapi(n) //run()函式可以傳遞Dog物件,也可以傳遞整數 def run(d:Dog) = print("hello world"); //呼叫隱式轉換函式。 scala> run(100) ; hello world 2.在單例物件中定義隱式轉換函式 //定義單例物件 object DogUtil{ //定義隱式轉換函式 implicit def str2Dog(s:String) = Jing8(s) ; } def run3(d:Dog) = println("hello world"); scala> run3(Jing8("tom")) hello world //錯誤是因為,方法是定義在單例類中的,需要先匯入才能使用 scala> run3("tom") <console>:17: error: type mismatch; found : String("tom") required: Dog run3("tom") //匯入之後就OK了 scala> import DogUtil._ import DogUtil._ scala> run3("tom") hello world 八、隱式引數 -------------------------------------------------------------- 1.引數預設值和帶名引數 def decorate(prefix:String = "[[[",c:String,suffix:String="]]]") = ... decorate(c= "hello world") 2.如果有50個函式,都有一個相同的引數,而且這個相同的引數具有相同的值。那麼就需要隱式引數了 //建立隱式變數,dog ==> Jing8("tomas") object DogUtil2{ implicit val dog = Jing8("tomas") ; } import DogUtil2._ //建立帶有隱式引數的函式 def run4(implicit dog:Jing8) = println("hello : ") ; run4();