Scala协方差与下界

时间:2014-06-07 20:27:54

标签: scala

我正在看动作书中的scala,它有这段代码

sealed abstract class Maybe[+A] {
    def isEmpty: Boolean
    def get: A
    def getOrElse[B >: A](default: B): B = {
        if(isEmpty) default else get
    }
}
    final case class Just[A](value: A) extends Maybe[A] {
    def isEmpty = false
    def get = value
}
case object Nil extends Maybe[scala.Nothing] {
    def isEmpty = true
    def get = throw new NoSuchElementException("Nil.get")
}

如果getOrElse的签名定义为     def getOrElse(默认值:A):A = 它没有编译。

作者说 “下限B>:A声明类型参数B被约束为某种类型A的超类型”

然而我似乎能够做到这一点并且有效

val j1 = Just(1)                                  
val l1 = j1.getOrElse("fdsf")  //l1  : Any = 1

String是超类型的Int吗?我不明白为什么这有效?它就像它回到参数1是类型A是Any类型(它是)而不是类型Int。

1 个答案:

答案 0 :(得分:3)

在Scala中,您不能在方法参数中使用协变类型。

这是因为允许方法参数中的协变类型会破坏类型安全性。

为了具有协变类型,您必须使用有界类型:

getOrElse[B >: A](default: B): B

这说找到一些类型B,这样它就是A的超类,并成为方法返回类型。

在您的情况下,AInt并且您传递了String。唯一类型BIntString的超类{/ 1}}。

在这种情况下,Any变为B,因此该方法会返回Any