scala-泛型

Scala學習——泛型[T]

6種使用

複製代碼
 1 package com.dtspark.scala.basics
 2 
 3 /**
 4  * 1,scala的類和方法、函數都可以是泛型。
 5  * 
 6 
 7  * 2,關於對類型邊界的限定分爲上邊界和下邊界(對類進行限制)
 8  * 上邊界:表達了泛型的類型必須是"某種類型"或某種類型的"子類",語法爲“<:”,
 9  * 下邊界:表達了泛型的類型必須是"某種類型"或某種類型的"父類",語法爲“>:”,
10  * 
11 
12  * 3, "<%" :view bounds可以進行某種神祕的轉換,把你的類型在沒有知覺的情況下轉換成目標類型,
13  * 其實你可以認爲view bounds是上下邊界的加強和補充,語法爲:"<%",要用到implicit進行隱式轉換(見下面例子)
14  * 
15 
16  * 4,"T:classTag":相當於動態類型,你使用時傳入什麼類型就是什麼類型,(spark的程序的編譯和運行是區分了Driver和Executor的,只有在運行的時候才知道完整的類型信息)
17  * 語法爲:"[T:ClassTag]"下面有列子
18  *
19 
20  * 5,逆變和協變:-T和+T(下面有具體例子)+T可以傳入其子類和本身(與繼承關係一至)-T可以傳入其父類和本身(與繼承的關係相反),
21  * 
22 
23  * 6,"T:Ordering" :表示將T變成Ordering[T],可以直接用其方法進行比大小,可完成排序等工作
24  */
25 
26 class Person(val name:String){
27   def talk(person:Person){
28     println(this.name+" speak to "+person.name)
29   }
30 }
31 
32 class Worker(name:String)extends Person(name)
33 
34 class Dog(val name:String)
35 
36 
37 
38 
39 //注意泛型用的是[]
40 class Club[T<:Person](p1:T,p2:T){//"<:"必須是person或person的子類
41   def comminicate = p1.talk(p2)
42 }
43 
44 
45 class Club2[T<%Person](p1:T,p2:T){
46   def comminicate = p1.talk(p2)
47 }
48 
49 class Engineer
50 class Expert extends Engineer
51 //如果是+T,指定類型爲某類時,傳入其子類或其本身
52 //如果是-T,指定類型爲某類時,傳入其父類或其本身
53 class Meeting[+T]//可以傳入T或T的子類
54 
55 class Maximum[T:Ordering](val x:T,val y:T){
56   def bigger(implicit ord:Ordering[T])={
57     if(ord.compare(x, y)>0)x else y
58   }
59 }
60 
61 object HelloScalaTypeSystem {
62   def main(args: Array[String]): Unit = {
63      val p= new Person("Spark")
64      val w= new Worker("Scala")
65      new Club(p,w).comminicate
66      
67 //"<%"的列子
68      //只是提供了一個轉換的方法,在遇到<%時會調用看dog是否被轉換了。
69      implicit def dog2Person(dog:Dog)=new Person(dog.name)
70      val d = new Dog("dahuang")
71      //注意必須強制類型轉換,implicit中雖然是將dog隱式轉換成person,
72      //但是其實是對象擦除,變成了object,所以還要強制類型轉換成person後才能使用
73      //用[person]強制轉換
74      new Club2[Person](p,d).comminicate
75      
76  //-T +T例子,下面的participateMeeting方法指定具體是什麼泛型
77      val p1=new Meeting[Engineer]
78      val p2=new Meeting[Expert]
79      participateMeeting(p1)
80      participateMeeting(p2)
81  // T:Ordering 的例子   
82      println(new Maximum(3,5).bigger)
83      println(new Maximum("Scala","Java").bigger)
84 
85      
86      
87   }
88   //這裏指定傳入的泛型具體是什麼
89   def participateMeeting(meeting:Meeting[Engineer])=  println("welcome")
90   
91 }
複製代碼

 

T:ClassTag的例子(根據輸入動態定義)

命令行代碼:

scala> import scala.reflect.ClassTag
import scala.reflect.ClassTag
 
scala> def mkArray[T: ClassTag](elems: T*) = Array[T](elems: _*)
mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T]
 
 
scala> mkArray(1,2,3)
res1: Array[Int] = Array(1, 2, 3)
 
scala> mkArray("ss","dd")
res2: Array[String] = Array(ss, dd)
scala> mkArray(1,"dd")
res2: Array[Any] = Array(1, dd)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章