2017-08-05 48 views
1

考慮下面的代碼工作:下界似乎不是協方差

class Animal 
class Cat extends Animal 
class BlackCat extends Cat 
class MyOption[+A](val x: A) { 
     def get(): A = x 
     def getOrElse[B >: A](default: => B): B = { 
     if (x != null) x else default 
     } 
} 

object ThirdParty { 
    def getAnimal : MyOption[Animal]= new MyOption[Cat](null) 
} 

object MyOptionRunner { 
    def main(args: Array[String]) { 
    val opt3: Animal = ThirdParty.getAnimal.getOrElse(new BlackCat) 
    println(opt3) 
    } 
} 

我感到意外的是val opt3: Animal = ThirdParty.getAnimal.getOrElse(new BlackCat)可以通過編譯。

類型的ThirdParty.getAnimal是Myption [貓],則該呼叫相當於 Myption[Cat].getOrElse(new BlackCat),它不符合getOrElse的定義,A是貓和B是黑貓這裏,打破B>:甲

回答

1
val opt3: Animal = ThirdParty.getAnimal.getOrElse(new BlackCat) 

B不是BlackCat; B的類型將是符合所需規格的最具體類型。由於參數是new BlackCat,我們知道B >: BlackCat。根據getOrElse的要求,我們知道B >: Cat。滿足這兩個要求的最具體的類型當然是Cat

+0

謝謝@ silvio-mayolo。然後,任何(任何類型的)可以是'getOrElse'的參數,例如:'ThirdParty.getAnimal.getOrElse(1)' – Tom

+0

沒錯。 'ThirdParty.getAnimal.getOrElse(1)'將返回一個類型爲「Any」的參數。我只是親自測試過它;它的工作原理就像你說的。 –