【发布时间】:2018-09-17 22:49:41
【问题描述】:
具体来说,看getOrElse。
Scala 的 Option 在 A 中被定义为协变的,如下所示:
sealed abstract class Option[+A] extends Product with Serializable {
self =>
@inline final def getOrElse[B >: A](default: => B): B =
if (isEmpty) default else this.get
}
getOrElse 的定义似乎暗示必须返回 A 的超类型,这对我来说并不一定很有意义。但实际上,它看起来像任何东西:子类型或超类型。
scala> class A
// defined class A
scala> class B extends A
// defined class B
scala> val optA: Option[A] = Option(null)
val optA: Option[A] = None
scala> optA.getOrElse(new B)
val res23: A = B@66a2c8e7
scala> class C extends B
// defined class C
scala> val optB: Option[B] = Option(null)
val optB: Option[B] = None
scala> optB.getOrElse(new A)
val res24: A = A@2a460bf
scala> optB.getOrElse(new C)
val res25: B = C@e87f97f
考虑到限制,这怎么可能?具体来说,鉴于getOrElse 的约束,我不明白optB.getOrElse(new C) 是如何被允许的(它应该返回Option 类型参数的超类型)。
【问题讨论】:
-
把它想象成三元运算符 /
if (c) new A else new B。 -
那么它继承了左值的类型(如果有的话)?好吧,有点道理。但是鉴于 getOrElse 的约束(它应该返回 Option 类型参数的超类型),我仍然不明白如何允许
optB.getOrElse(new C)。我会修改我的问题。 -
好吧,如果您查看打印的
res25的类型,它会说类型是B,这似乎是完美的。其操作数的最大通用超类型。 -
expr
new C其类型为 C 被隐式转换为类型B -
啊,我明白了,只是使用任何类型都可以毫无问题地被视为自身的超类型的基本属性。
标签: scala types scala-collections variance type-bounds