2017-08-05 57 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”的参数。我只是亲自测试过它;它的工作原理就像你说的。 –