scala lower type bounds示例

时间:2015-08-19 08:07:19

标签: scala types

我有以下代码:

class A[+X] {
  def printY[Y >: X](y: Y) = println(y)
}

class F
class G extends F

val f = new F
val g = new G

val a = new A[F]
a.printY(g)

我预计a.printY(g)中的编译错误g的类型G不是F的超类型。但在class A中,我指出printY方法仅接受A类型参数的超类型,在我的示例中为F

为什么它能正常工作?

3 个答案:

答案 0 :(得分:3)

因为g 也是 F的实例。因此,Y被推断为F,这是F的超类型。即:

a.printY[F](g)

然而,这不会编译:

a.printY[G](g)

答案 1 :(得分:2)

注意:如果希望 a.printY(g)不编译,则需要重写方法:

def printY[Y](y: Y)(implicit ev: X <:< Y) = println(y)

这样编译器会将类型参数推断为G,然后然后检查它是否是F的超类型,而不是寻找F的超类型1}}这也恰好是g的可接受类型。

答案 2 :(得分:1)

试着从另外两个角度解释它为什么会起作用。

首先,如您所知,上限是 reflexive ,对于Y&gt;:X,Y的类型X或子类型是可接受的。因此,当您定义val a = new A[F]时,printY将如下:

def printY[Y >: F](y: Y) = println(y)

当您调用a.printY(g)时,printY的类型参数将被推断为G,这也是F的类型。

其次,对于def printY[Y >: F](y: Y) = println(y),当您传递Y类型的实例I时,编译器将尝试查找I和F的公共父,并将结果类型作为类型参数of printY,所以你甚至可以将String,Int的值传递给printY。

a.printY[Any]("xxx")
a.printY[Any](3)