我正在看动作书中的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。
答案 0 :(得分:3)
在Scala中,您不能在方法参数中使用协变类型。
这是因为允许方法参数中的协变类型会破坏类型安全性。
为了具有协变类型,您必须使用有界类型:
getOrElse[B >: A](default: B): B
这说找到一些类型B
,这样它就是A
的超类,并成为方法返回类型。
在您的情况下,A
为Int
并且您传递了String
。唯一类型B
是Int
和String
的超类{/ 1}}。
在这种情况下,Any
变为B
,因此该方法会返回Any
。