欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

scala的型變是什么

本篇內(nèi)容介紹了“scala的型變是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

為薛城等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及薛城網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、薛城網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

型變是復(fù)雜類型的子類型關(guān)系與其組件類型的子類型關(guān)系的相關(guān)性。Scala支持 泛型類 的類型參數(shù)的型變注釋,允許它們是協(xié)變的,逆變的,或在沒有使用注釋的情況下是不變的。在類型系統(tǒng)中使用型變?cè)试S我們?cè)趶?fù)雜類型之間建立直觀的連接,而缺乏型變則會(huì)限制類抽象的重用性。

class Foo[+A] // A covariant classclass Bar[-A] // A contravariant classclass Baz[A]  // An invariant class

協(xié)變

使用注釋 +A,可以使一個(gè)泛型類的類型參數(shù) A 成為協(xié)變。對(duì)于某些類 class List[+A],使 A 成為協(xié)變意味著對(duì)于兩種類型 AB,如果 AB 的子類型,那么 List[A] 就是 List[B] 的子類型。這允許我們使用泛型來創(chuàng)建非常有用和直觀的子類型關(guān)系。

考慮以下簡(jiǎn)單的類結(jié)構(gòu):

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

類型 CatDog 都是 Animal 的子類型。Scala 標(biāo)準(zhǔn)庫(kù)有一個(gè)通用的不可變的類 sealed abstract class List[+A],其中類型參數(shù) A 是協(xié)變的。這意味著 List[Cat]List[Animal],List[Dog] 也是 List[Animal]。直觀地說,貓的列表和狗的列表都是動(dòng)物的列表是合理的,你應(yīng)該能夠用它們中的任何一個(gè)替換 List[Animal]。

在下例中,方法 printAnimalNames 將接受動(dòng)物列表作為參數(shù),并且逐行打印出它們的名稱。如果 List[A] 不是協(xié)變的,最后兩個(gè)方法調(diào)用將不能編譯,這將嚴(yán)重限制 printAnimalNames 方法的適用性。

object CovarianceTest extends App {  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"))
 printAnimalNames(cats)  printAnimalNames(dogs)}

逆變

通過使用注釋 -A,可以使一個(gè)泛型類的類型參數(shù) A 成為逆變。與協(xié)變類似,這會(huì)在類及其類型參數(shù)之間創(chuàng)建一個(gè)子類型關(guān)系,但其作用與協(xié)變完全相反。也就是說,對(duì)于某個(gè)類 class Writer[-A] ,使 A 逆變意味著對(duì)于兩種類型 AB,如果 AB 的子類型,那么 Writer[B]Writer[A] 的子類型。

考慮在下例中使用上面定義的類 Cat,DogAnimal

abstract class Printer[-A] {  def print(value: A): Unit}

這里 Printer[A] 是一個(gè)簡(jiǎn)單的類,用來打印出某種類型的 A。讓我們定義一些特定的子類:

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)}

如果 Printer[Cat] 知道如何在控制臺(tái)打印出任意 Cat,并且 Printer[Animal] 知道如何在控制臺(tái)打印出任意 Animal,那么 Printer[Animal] 也應(yīng)該知道如何打印出 Cat 就是合理的。反向關(guān)系不適用,因?yàn)?Printer[Cat] 并不知道如何在控制臺(tái)打印出任意 Animal。因此,如果我們?cè)敢?,我們?yīng)該能夠用 Printer[Animal] 替換 Printer[Cat],而使 Printer[A] 逆變?cè)试S我們做到這一點(diǎn)。

object ContravarianceTest extends App {  val myCat: Cat = Cat("Boots")
 def printMyCat(printer: Printer[Cat]): Unit = {    printer.print(myCat)  }
 val catPrinter: Printer[Cat] = new CatPrinter  val animalPrinter: Printer[Animal] = new AnimalPrinter
 printMyCat(catPrinter)  printMyCat(animalPrinter)}

這個(gè)程序的輸出如下:

The cat's name is: BootsThe animal's name is: Boots

不變

默認(rèn)情況下,Scala中的泛型類是不變的。這意味著它們既不是協(xié)變的也不是逆變的。在下例中,類 Container 是不變的。Container[Cat] 不是 Container[Animal],反之亦然。

class Container[A](value: A) {  private var _value: A = value  def getValue: A = _value  def setValue(value: A): Unit = {    _value = value  }}

可能看起來一個(gè) Container[Cat] 自然也應(yīng)該是一個(gè) Container[Animal],但允許一個(gè)可變的泛型類成為協(xié)變并不安全。在這個(gè)例子中,Container 是不變的非常重要。假設(shè) Container 實(shí)際上是協(xié)變的,下面的情況可能會(huì)發(fā)生:

val catContainer: Container[Cat] = new Container(Cat("Felix"))val animalContainer: Container[Animal] = catContaineranimalContainer.setValue(Dog("Spot"))val cat: Cat = catContainer.getValue
幸運(yùn)的是,編譯器在此之前就會(huì)阻止我們。

其他例子

另一個(gè)可以幫助理解型變的例子是 Scala 標(biāo)準(zhǔn)庫(kù)中的 trait Function1[-T, +R]。Function1 表示具有一個(gè)參數(shù)的函數(shù),其中第一個(gè)類型參數(shù) T 表示參數(shù)類型,第二個(gè)類型參數(shù) R 表示返回類型。Function1 在其參數(shù)類型上是逆變的,并且在其返回類型上是協(xié)變的。對(duì)于這個(gè)例子,我們將使用文字符號(hào) A => B 來表示 Function1[A, B]。

假設(shè)前面使用過的類似 CatDog,Animal 的繼承關(guān)系,加上以下內(nèi)容:

abstract class SmallAnimal extends Animalcase class Mouse(name: String) extends SmallAnimal

假設(shè)我們正在處理接受動(dòng)物類型的函數(shù),并返回他們的食物類型。如果我們想要一個(gè) Cat => SmallAnimal(因?yàn)樨埑孕?dòng)物),但是給它一個(gè) Animal => Mouse,我們的程序仍然可以工作。直觀地看,一個(gè) Animal => Mouse 的函數(shù)仍然會(huì)接受一個(gè) Cat 作為參數(shù),因?yàn)?Cat 即是一個(gè) Animal,并且這個(gè)函數(shù)返回一個(gè) Mouse,也是一個(gè) SmallAnimal。既然我們可以安全地,隱式地用后者代替前者,我們可以說 Animal => MouseCat => SmallAnimal 的子類型。

與其他語言的比較

某些與 Scala 類似的語言以不同的方式支持型變。例如,Scala 中的型變注釋與 C# 中的非常相似,在定義類抽象時(shí)添加型變注釋(聲明點(diǎn)型變)。但是在Java中,當(dāng)類抽象被使用時(shí)(使用點(diǎn)型變),才會(huì)給出型變注釋。

“scala的型變是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

本文名稱:scala的型變是什么
網(wǎng)站URL:http://aaarwkj.com/article36/gdsdsg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站定制開發(fā)、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)

網(wǎng)站設(shè)計(jì)公司知識(shí)

av在线男人社区日韩| 亚洲国产精品一区二区三区在线| 91欧美精品综合在线| 中文字幕精品一区二区三区精品| 啊啊…嗯嗯…用力免费观看视频| 精品一区精品二区国产日韩| 国产一区二区三区av网站| 一级黄片一区二区三区| 亚洲午夜精品毛片成人| 密臀精品国产一区二区| 真做的欧美三级在线观看| 亚洲女人淫片在线观看| 国产精品久久久久久久av三级| 日本黄色小网站在线播放| 欧美日韩在线不卡一区| 好吊毛片一区二区三区| 国产精品一区二在线观看| 日本中文字幕乱码一区| 超薄丝袜美腿一二三区在线播放 | 国产又黄又爽不卡的视频| 国产亚洲国产av网站在线| 国产日韩欧美一区综合| 亚洲精品一区二区播放| 中文字幕亚洲精品乱码在线| 亚洲国产成人av精品精品国产自 | 欧美日韩一区二区黄色| 欧美亚洲一区二区三区精品| 国产精品日本欧美一区二区| 亚洲国产中文字幕高清| 国内熟妇人妻色在线三级| 激情四射五月天亚洲婷婷| 欧美激情亚洲一区二区| 日韩中文字幕视频久久| av一区二区三区不卡在线看| 亚洲精品第一国产综合| 国产精品精品久久久久久| 国产欧美成人综合色就色| 日本高清加勒比免费在线| 国产高清亚洲一区亚洲二区| 黄色黄色片黄色片黄色| 精品视频中文字幕天码|