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
。