- 泛型
- 类型变量bounds
- View Bound
- Context Bounds
- Manifest ClassTag
- 多重界定
- 类型约束
- 协变 逆变
泛型
class Triple[T, P, S](val a : T, val b : P, val c :S)
val triple = new Triple("Spark", 3, 3.141592654)
val bigData = new Triple[String, String, Char]("Spark","scala",'c')
def getData[T](list : List[T]) = list(list.length/2)
println(getData(List("Spark","Hadoop",'R')))
val f = getData[Int] _
println(f(List(1,2,3,4,5)))
def biuldArray[T : ClassTag](len : Int) = new Array[T](len)
println(biuldArray[Int](5).toList)
类型变量bounds
//T是Comparable[T]的子类
class Pair[T <: Comparable[T]](val first : T, val second : T){
def bigger = if(first.compareTo(second) > 0)first else second
}
//R是T的父类
class Pair_Lower_Bound[T](val first : T, val second : T){
def replaceFirst[R >: T](newFirst : R) = new Pair_Lower_Bound[R](newFirst, second)
}
val pair =new Pair("Spark","Hadoop")
println(pair.bigger)
View Bound
class Pair_NotPerfect[T <% Comparable[T]](val first : T, val second : T){
def bigger = if(first.compareTo(second) > 0)first else second
}
class Pair_Better[T <% Ordered[T]](val first : T, val second : T){
def bigger = if(first > second)first else second
}
//隐式转换Int => richInt
val pairInt =new Pair_NotPerfect(3, 5)
println(pairInt.bigger)
//隐式转换String => richString
val pairString =new Pair_NotPerfect("Spark", "Hadoop")
println(pairInt.bigger)
val pairInt_Pair_Better =new Pair_Better(20, 50)
println(pair_Pair_Better.bigger)
val pair_Pair_Better =new Pair_Better("Spark", "Hadoop")
println(pair_Pair_Better.bigger)
Context Bounds
class Pair_Ordering[T : Ordering](val first : T, val second : T){
def bigger(implicit ordered : Ordering[T]) = {
if (ordered.compare(first, second) > 0) first else second
}
}
val pair = new Pair_Ordering("Spark", "Hadoop")
println(pair.bigger)
val pairInt = new Pair_Ordering(3, 5)
println(pairInt.bigger)
Manifest/ ClassTag
def arrayMake[T : Manifest](first : T, second : T) = {
val r = new Array[T](2)
r(0) = first
r(1) = second
r
}
arrayMake(1, 2).foreach(println)
def manif[T](x : List[T])(implicit m : Manifest[T]) ={
if (m <:< manifest[String])
println("List strings")
else {
println("Some other type")
}
}
manif(List("Spark", "Hadoop"))
manif(List(1, 2))
manif(List("Scala", 3))
class A[T]
val m = manifest[A[String]]
println(m)
val cm = classManifest[A[String]]
println(cm)
def mkArray[T : ClassTag](elems : T*) = Array[T](elems : _*)
mkArray(42,13).foreach(println)
mkArray("Japan","Brazil","Germany").foreach(println)
多重界定
//T是A和B的子类
def fun[T <: A with B]
//下界是A上界是B
def fun[T >: A <: B]
//T : A &&T :B
def fun[T : A : B]
//T通过隐式转换可以转AB
def fun[T <% A <% B]
类型约束
// A =:= B //表示A类型同等于B
// A <:< B //表示A类型是B类型的子类型
def fun[T](i : T)(implicit x : T <:< java.io.Serializable){
println("Great")
fun("Scala")
//fun(1) X
协变/ 逆变
//A>:B List[A]>:List[B]是协变
//A>:B List[A]<:List[B]是逆变
//协变+逆变-
class P[+T](val first : T, val second : T){
def replaceFirst[R >: T](newFirst : R) = new P[R] (newFirst, second)
}