【问题标题】:Types in Scala - lower boundsScala 中的类型 - 下界
【发布时间】:2013-10-13 14:01:28
【问题描述】:

下面的代码。

我的期望是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
}

【问题讨论】:

    标签: scala generics type-bounds


    【解决方案1】:

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

    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 只是一个不好的例子,因为这个方法有所有对象类型,但是如果你把它改成,比如someMethod,你的lowerBound 将无法编译:

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

    如果你把它改成T &lt;: B,这意味着T类型的参数是B的子类,那么一切都很好,因为这个paramsomeMethod方法:

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

    【讨论】:

    • 亚历克斯,感谢您的回答。真正让我感到奇怪的是,我必须使用 someMethod 才能看到编译时错误。但是,当我运行 def upperBound[T &lt;: B](param: T) = { param }; println(upperBound(new A)); 编译器时,编译器对我咆哮,而没有任何方法调用。这对我来说仍然不清楚......如果可以吃AnyRef,并且不能对类型本身做出任何假设,如何在这里确保编译时类型安全?......
    • @MaxP。 AB 的超类型,您正在写的是您的参数可以采用T 类型的对象,该类型至少为B。但是如果你的B 类有someMethod,而A 它的超类型没有呢?如果你不明白这些事情,请用 key 调用 repl:-Xprint:typer,它会告诉你 scalac typer 阶段在做什么
    • 亚历克斯,我刚刚重读了你的答案,一个灯泡亮了:D - 你说过 - 我们至少希望 BDB。所以明白了!谢谢。
    【解决方案2】:

    也面临同样的问题。似乎编译器在帮助我们站稳脚跟方面做得很好。如果您提取 lowerBound 的结果,您可能会注意到它的类型为 B

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

    然后,如果您尝试明确请求类型 D

    lowerBound[D](new D)
    

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

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

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多