scala类型下限示例

scala类型下限示例,scala,types,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 为什么它工作正常?因

我有以下代码:

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

为什么它工作正常?

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

a.printY[F](g)
但是,这不会编译:

a.printY[G](g)
因为
g
也是
F
的一个实例。因此,
Y
被推断为
F
,这是
F
的超类型。即:

a.printY[F](g)
但是,这不会编译:

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

def printY[Y](y: Y)(implicit ev: X <:< Y) = println(y)
def printY[Y](Y:Y)(隐式ev:X注意:如果希望
a.printY(g)
不编译,则需要重写该方法:

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

defprinty[Y](Y:Y)(隐式ev:X试着从另外两个角度解释它为什么工作

首先,正如您所知,上界是自反的,对于Y>:X,类型X或Y的子类型是可以接受的。因此,当您定义
val a=new a[F]
时,printY将类似于:

def printY[Y >: F](y: Y) = println(y)
调用a.printY(g)时,printY的type参数将被推断为g,它也是F的一种类型

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

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

试着从另外两个角度解释它为什么有效

首先,正如您所知,上界是自反的,对于Y>:X,类型X或Y的子类型是可以接受的。因此,当您定义
val a=new a[F]
时,printY将类似于:

def printY[Y >: F](y: Y) = println(y)
调用a.printY(g)时,printY的type参数将被推断为g,它也是F的一种类型

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

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

+1,很好的附录。我还要补充一点,您仍然可以手动将
Y
设置为
F
a.printY[F](g)
-我认为这是无法避免的。@Zapadlo 1.当你例如将
A
添加到
B
的列表中时,你会得到
A
B
的最不常见的超类型列表,这正是你从较低类型边界得到的行为;2.当使用较低类型的方法时,你可以得到更有趣的行为绑定到
Y
不只是接受
Y
+1,很好的附录。我还要补充一点,您仍然可以手动将
Y
设置为
F
a.printY[F](g)
-我认为这是无法避免的。@Zapadlo 1.当你例如将
A
添加到
B
的列表中时,你会得到
A
B
的最不常见的超类型列表,这正是你从较低类型边界得到的行为;2.当使用较低类型的方法时,你可以得到更有趣的行为绑定在
Y
上不仅仅接受
Y