[英]scala lower type bounds example
I have the following code: 我有以下代码:
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)
I expect a compilation error in a.printY(g)
as g
has type G
which is not a supertype of F
. 我期望
a.printY(g)
出现编译错误,因为g
类型为G
,而不是F
的超类型。 But in class A
I indicated that printY
method only accepts supertype of A
's type paramter which is F
in my example. 但是在
class A
我指出printY
方法仅接受A
的类型参数的超类型,在我的示例中为F
Why it works correctly? 为什么它可以正常工作?
Because g
is also an instance of F
. 因为
g
也是 F
的实例。 Therefore, Y
is inferred as F
, which is a supertype of F
. 因此,将
Y
推断为F
,它是F
的超类型。 Ie: 即:
a.printY[F](g)
However, this wouldn't compile: 但是,这不会编译:
a.printY[G](g)
Note: if you want a.printY(g)
not to compile you need to rewrite the method: 注意:如果不希望
a.printY(g)
进行编译,则需要重写该方法:
def printY[Y](y: Y)(implicit ev: X <:< Y) = println(y)
This way the compiler infers the type parameter to be G
and then checks whether it's a supertype of F
instead of looking for a supertype of F
which also happens to be an acceptable type for g
. 这样,编译器将类型参数推断为
G
, 然后检查它是否是F
的超类型,而不是查找F
的超类型,而F
恰好也是g
的可接受类型。
Just try to explain why it works from another two angles. 请尝试从另外两个角度解释它的工作原理。
First, as you know the upper bound is reflexive
, for Y >: X, type X or subtype of Y is acceptable. 首先,您知道上限是
reflexive
,对于Y>:X,可以接受类型X或Y的子类型。 so when you define val a = new A[F]
, printY will be like: 因此,当您定义
val a = new A[F]
,printY将类似于:
def printY[Y >: F](y: Y) = println(y)
when you invoke a.printY(g), printY's type parameter will be inferred as G, which is also a type of F. 当您调用a.printY(g)时,printY的type参数将被推断为G,这也是F的类型。
Second, for def printY[Y >: F](y: Y) = println(y)
, when you pass an instance I of type Y, compiler will try to find the common parent of I and F and make the resultant type as the type parameter of printY, so you can even pass value of String, Int to printY. 其次,对于
def printY[Y >: F](y: Y) = println(y)
,当您传递类型为Y的实例I时,编译器将尝试查找I和F的公共父级 ,并使结果类型为printY的类型参数,因此您甚至可以将String,Int的值传递给printY。
a.printY[Any]("xxx")
a.printY[Any](3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.