简体   繁体   English

Scala下限类型示例

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM