真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

好程序員大數(shù)據(jù)學(xué)習(xí)路線分享Scala系列之泛型

好程序員大數(shù)據(jù)學(xué)習(xí)路線分享Scala系列之泛型,帶有一個或多個類型參數(shù)的類是泛型的。

創(chuàng)新互聯(lián)長期為近千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為青川企業(yè)提供專業(yè)的做網(wǎng)站、網(wǎng)站建設(shè),青川網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

泛型類的定義:

//帶有類型參數(shù)A的類定義
class Stack[A] {
private var elements: List[A] = Nil
//泛型方法
def push(x: A) { elements = x :: elements }
def peek: A = elements.head
def pop(): A = {
val currentTop = peek
elements = elements.tail
currentTop
}
}

泛型類的使用,用具體的類型代替類型參數(shù)A。

val stack = new Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop) // prints 2
println(stack.pop) // prints 1

1.協(xié)變
定義一個類型List[+A],如果A是協(xié)變的,意思是:對類型A和B,A是B的子類型,那么List[A]是List[B]的子類型。

abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal

Scala標(biāo)準(zhǔn)庫有一個泛型類sealed abstract class List[+A],因?yàn)槠渲械念愋蛥?shù)是協(xié)變的,那么下面的程序調(diào)用時成功的。

object CovarianceTest extends App {
//定義參數(shù)類型List[Animal]
def printAnimalNames(animals: List[Animal]): Unit = {
animals.foreach { animal =>
println(animal.name)
}
}

val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))
val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex"))
//傳入?yún)?shù)類型為List[Cat]
printAnimalNames(cats)
// Whiskers
// Tom
//傳入?yún)?shù)類型為List[Dog]
printAnimalNames(dogs)
// Fido
// Rex
}

2.逆變
定義一個類型Writer[-A],如果A是逆變的,意思是:對類型A和B,A是B的子類型,那么Writer[B]是Writer[A]的子類型。

abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal

定義對應(yīng)上述類進(jìn)行操作的打印信息類

abstract class Printer[-A] {
def print(value: A): Unit
}
class AnimalPrinter extends Printer[Animal] {
def print(animal: Animal): Unit =
println("The animal's name is: " + animal.name)
}

class CatPrinter extends Printer[Cat] {
def print(cat: Cat): Unit =
println("The cat's name is: " + cat.name)
}

逆變的測試

object ContravarianceTest extends App {
val myCat: Cat = Cat("Boots")

//定義參數(shù)類型為Printer[Cat]
def printMyCat(printer: Printer[Cat]): Unit = {
printer.print(myCat)
}

val catPrinter: Printer[Cat] = new CatPrinter
val animalPrinter: Printer[Animal] = new AnimalPrinter

printMyCat(catPrinter)
//可以傳入?yún)?shù)類型為Printer[Animal]
printMyCat(animalPrinter)
}

3.上界
上界定義: T <: A ,表示類型變量T 必須是 類型A 子類

abstract class Animal {
def name: String
}

abstract class Pet extends Animal {}

class Cat extends Pet {
override def name: String = "Cat"
}

class Dog extends Pet {
override def name: String = "Dog"
}

class Lion extends Animal {
override def name: String = "Lion"
}
//參數(shù)類型須是Pet類型的子類
class PetContainer[P <: Pet](p: P) {
def pet: P = p
}
//Dog是Pet類型的子類
val dogContainer = new PetContainer[Dog](new Dog)
//Cat是Pet類型的子類
val catContainer = new PetContainer[Cat](new Cat)
//Lion不是Pet類型的子類,編譯通不過
// val lionContainer = new PetContainer[Lion](new Lion)

4.下界
語法 B >: A 表示參數(shù)類型或抽象類型 B 須是類型A的父類。通常,A是類的類型參數(shù),B是方法的類型參數(shù)。

好程序員大數(shù)據(jù)學(xué)習(xí)路線分享Scala系列之泛型

上面這段代碼,因?yàn)樽鳛閰f(xié)變類型的B,出現(xiàn)在需要逆變類型的函數(shù)參數(shù)中,導(dǎo)致編譯不通過。解決這個問題,就需要用到下界的概念。

trait Node[+B] {
def prepend[U >: B](elem: U): Node[U]
}

case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this)
def head: B = h
def tail: Node[B] = t
}

case class Nil[+B]() extends Node[B] {
def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this)
}

測試

trait Bird
case class AfricanSwallow() extends Bird
case class EuropeanSwallow() extends Bird

val africanSwallowList= ListNode[AfricanSwallow](AfricanSwallow(), Nil())
val birdList: Node[Bird] = africanSwallowList
birdList.prepend(new EuropeanSwallow)

5 視界(view bounds)
注意:已過時,了解即可

視界定義: A <% B ,表示類型變量A 必須是 類型B`的子類,或者A能夠隱式轉(zhuǎn)換到B

class Pair_Int[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 smaller = if(first < second) first else second
}
object View_Bound {

def main(args: Array[String]) {
// 因?yàn)镻air[String] 是Comparable[T]的子類型, 所以String有compareTo方法
val pair = new Pair_Int("Spark", "Hadoop");
println(pair.bigger)

/**
  * Scala語言里 Int類型沒有實(shí)現(xiàn)Comparable;
  * 那么該如何解決這個問題那;
  * 在scala里 RichInt實(shí)現(xiàn)了Comparable, 如果我們把int轉(zhuǎn)換為RichInt類型就可以這樣實(shí)例化了.
  * 在scala里 <% 就起這個作用, 需要修改Pair里的 <: 為<% 把T類型隱身轉(zhuǎn)換為Comparable[Int]
  * String可以被轉(zhuǎn)換為RichString. 而RichString是Ordered[String] 的子類.
  */
val pair_int = new Pair_Int(3 ,45)
println(pair_int.bigger)

val pair_better = new Pair_Better(39 ,5)
println(pair_better.smaller)

}

}

6 上下文界定(context bounds)
上下文界定的形式為 T : M, 其中M 必須為泛型類, 必須存在一個M[T]的隱式值.

class Pair_Context[T : Ordering](val first: T, val second: T){
def smaller(implicit ord: Ordering[T]) =
if(ord.compare(first, second) < 0) first else second
}

object Context_Bound {

def main(args: Array[String]) {

val pair = new Pair_Context("Spark", "Hadoop")
println(pair.smaller)

val int = new Pair_Context(3, 5)
println(int.smaller)

}

}


當(dāng)前名稱:好程序員大數(shù)據(jù)學(xué)習(xí)路線分享Scala系列之泛型
當(dāng)前地址:http://weahome.cn/article/pihssj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部