Reputation: 6332
Given the following code:
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)
}
}
I am surprised that val opt3: Animal = ThirdParty.getAnimal.getOrElse(new BlackCat)
can pass the compiling.
The type of ThirdParty.getAnimal
is Myption[Cat],then the call is equivalent to
Myption[Cat].getOrElse(new BlackCat),
it doesn't conform to the definition of getOrElse, A is Cat and B is BlackCat here, which breaks B>:A
Upvotes: 1
Views: 44
Reputation: 70267
val opt3: Animal = ThirdParty.getAnimal.getOrElse(new BlackCat)
B
is not BlackCat
; the type of B
will be the most specific type that conforms to the specification required. Since the argument is new BlackCat
, we know that B >: BlackCat
. By the requirement of getOrElse
, we know that B >: Cat
. The most specific type that satisfies both of these requirements is, naturally, Cat
.
Upvotes: 1