3

在下面的代码上。

我的期望是它T必须是Bor类型A,所以调用 tolowerBound(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
}
4

2 回答 2

5

通过您的实现,您可以编写:

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

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

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

你只是有一个不好的例子toString,因为这个方法有所有的对象类型,但是如果你把它改成,比如说 on someMethod,你lowerBound就不会编译:

<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方法:

def lowerBound[T <: B](param: T) = { param.someMethod }
于 2013-10-07T05:16:04.197 回答
4

也面临同样的问题。似乎编译器在帮助我们站稳脚跟方面做得很好。如果您提取 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](new D)

于 2019-03-20T15:31:51.167 回答