Scala中的类型 - 下限

时间:2013-10-07 04:58:14

标签: scala generics type-bounds

代码如下。

我的期望是T必须是BA类型,因此调用lowerBound(new D)可能不应该编译(?)。上限的类似实验给出了预期的类型检查错误。

感谢您提供提示。

object varianceCheck {
  class A {
    override def toString = this.getClass.getCanonicalName
  }

  class B extends A
  class C extends B
  class D extends C

  def lowerBound[T >: B](param: T) = { param }

  println(lowerBound(new D))                      //> varianceCheck.D
}

2 个答案:

答案 0 :(得分:4)

通过实施,您可以写下:

scala>   def lowerBound[T >: B](param: T) = { param }
lowerBound: [T >: B](param: T)T

scala> lowerBound(new AnyRef {})
res0: AnyRef = $anon$1@2eef224

其中AnyRef是所有对象/引用类型的超类型(实际上它是Java Object类的别名)。这是正确的,T >: B表示类型参数T或抽象类型T引用类型B的超类型。

你只有toString的错误示例,因为此方法包含所有对象类型,但是如果将其更改为,请说someMethodlowerBound将无法编译:

<console>:18: error: value someMethod is not a member of type parameter T
       def lowerBound[T >: B](param: T) = { param.someMethod }

如果您将其更改为T <: B,这意味着T类型的参数是B的子类,那么一切都很好,因此paramsomeMethod 1}}方法:

def lowerBound[T <: B](param: T) = { param.someMethod }

答案 1 :(得分:3)

也遇到同样的问题。似乎编译器做得很出色,可以帮助我们立足。如果提取lowerBound的结果,您可能会注意到它的类型为B

val b: B = lowerBound(new D)
println(b)                      //> varianceCheck.D

然后,如果您尝试显式请求D类型

lowerBound[D](new D)

您将看到预期的编译器错误:

  

错误:(12,21)类型参数[D]不符合方法lowerBound的类型参数界限[T>:B]   lowerBound [D](新D)