溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Scala的泛型

發(fā)布時間:2020-07-22 17:42:01 來源:網絡 閱讀:661 作者:原生zzy 欄目:開發(fā)技術

Scala的泛型

泛型介紹:泛型用于指定方法或類可以接受任意類型參數(shù),參數(shù)在實際使用時才被確定,泛型可以有效 地增強程序的適用性,使用泛型可以使得類或方法具有更強的通用性。泛型的典型應用場景 是集合及集合中的方法參數(shù)。
泛型方法:指定方法可以接受任意類型參數(shù)。
泛型類:指定類可以接受任意類型參數(shù)。
例:

object GenericTypeTest01 {
def main(args: Array[String]): Unit = {
println(new Student11[String,Int]("黃渤",33).name)
println(new Student12[String,Int]("zs",18).name)
println(new Student22[String,Int]("zs",8).age)
  }
}
class Student12[T,S](var name:T,var age:S){}
class Student11[T,S](var name:T, var age:S){}
class Person11[T](var name:T)
class Student22[T,S](name:T,var age:S) extends Person11(name) {}

 1. scala類型變量界定

  類型變量界定是指在泛型的基礎上,對泛型的范圍進行進一步的界定,從而縮小泛型的具體范圍。
例:

object Test01 {
  def main(args: Array[String]): Unit = {
    var generic=new Generic
    val result: Int = generic.compare("aa","bb")
  }
}
class Generic{
  /**
    *T<:Comparable 表示compare方法中如果輸入的類型處于Comparable類對應的繼承體系中,則是合法的,否則編譯不通過
    * 作用是:當調用泛型的方法是,但是不知道這個泛型是否有這個方法,此時使用泛型的類型變量界定,縮寫范圍,使得,泛型中有這個方法
    */
  def compare[T<:Comparable[T]](first:T,second:T)={
    val result=if(first.compareTo(second)>0) 1 else 0
    result
  }
}

 2. scala視圖界定

  類型變量界定建立在類繼承的層次上,但有時候這種限定不能滿足實際要求,如果希望跨越類繼承層次結構時,可以使用視圖界定來實現(xiàn),原理是通過隱式轉換來實現(xiàn)。
  隱含參數(shù)和方法也可以定義隱式轉換,稱作視圖。視圖的綁定從另一個角度看就是 implicit 的轉換。其實視圖的綁定就是為了更方便的使用隱式轉化,視圖界定利用<%符號來實現(xiàn)。
例:

object Test01 {
  def main(args: Array[String]): Unit = {
    var ann1 = new Animals("zs", "18")
    var ann2 = new Animals("zs", 18)
  }
}
case class Animals[T, S <: Comparable[S]](var name: T, var age: S)

此時如果在[T, S <: Comparable[S]]使用<:的話,在運行的時候會報錯
Scala的泛型
因為:在類型變量界定的使用,默認的只能界定的類的是繼承體系中的一員才成立,如果是使用隱式轉換的方式默認不成立。上面代碼:String類繼承了Comparable,但是Int沒有繼承Comparable,只是隱式的將Int轉換成了RichInt,RichInt繼承了Comparable,所以此處出現(xiàn)了錯誤。
如果想隱式轉換也可以通過泛型的話可以:

object Test01 {
  def main(args: Array[String]): Unit = {
    var ann1 = new Animals("zs", "18")
    var ann2 = new Animals("zs", 18)
  }
}
case class Animals[T, S <% Comparable[S]](var name: T, var age: 

利用<%號對泛型 S 進行限定,它的意思是 S 可以是 Comparable 類繼承層次結構中實現(xiàn)了 Comparable 接口的類,也可以是能夠經過隱式轉換得到的實現(xiàn)了 Comparable 接口的類

 3. scala上界下界

  在指定泛型類型時,有時需要界定泛型類型的范圍,而不是接收任意類型。比如,要求某個 泛型類型,必須是某個類的子類,這樣在程序中就可以放心的調用父類的方法,程序才能正 常的使用與運行。此時,就可以使用上下邊界 Bounds 的特性; Scala 的上下邊界特性允許泛型類型是某個類的子類,或者是某個類的父類。
   U>:T這是類型下界的定義,也就是 U 必須是類型 T 的父類(或本身,自己也可以認為是自己的父 類)。
   S<:T這是類型上界的定義,也就是 S 必須是類型 T 的子類(或本身,自己也可以認為是自己的子 類)。
Scala的泛型
上界

class Generic2{
//指定上界,T必須是Comparable的子類或者是Comparable
def compare[T<:Comparable[T]] (first:T,second:T) ={
  }
}

下界

class Generic3{
//指定下界,T必須是Comparable的父類或者是Comparable
def compare[T>:Comparable[T]] (first:T,second:T) ={
  }
}

 4. scala逆變和逆變
  • 協(xié)變
     協(xié)變定義形式如:trait List[+T]{}
     當類型 B 是類型 A 的子類型時,則 List[B]也可以認為是 List[A}的子類型,即 List[B]可以泛化 為 List[A]。也就是被參數(shù)化類型的泛化方向與參數(shù)類型的方向是一致的,所以稱為協(xié)變 (covariance)
    Scala的泛型
    例:
    object Test01 {
    def main(args: Array[String]): Unit = {
    var list1:MyList[Person]=new MyList(new Person)
    var list2:MyList[Son]=new MyList(new Son)
    list1=list2
    }
    }
    class Person
    class Son extends Person
    class MyList[+T](val value:T)

    這種方式,在list中只能將子類轉化成為父類的list,如果在轉變之后,這個list中也只能存放子類的類型對象。協(xié)變的性質:輸入的類型必須是 Son 的超類。

  • 逆變
     逆變定義形式如:trait List[-T]{}
     當類型 B 是類型 A 的子類型,則 Queue[A]反過來可以認為是 Queue[B}的子類型。也就是被參數(shù)化類型的泛化方向與參數(shù)類型的方向是相反的,所以稱為逆變(contravariance)。
    Scala的泛型

  • 總結
    • 協(xié)變(covariant),如果它保持了子類型序關系≦。該序關系是:子類型≦基類型。
    • 逆變(contravariant),如果它逆轉了子類型序關系。
    • 不變(invariant),如果上述兩種均不適用。
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI