【问题标题】:Scala lower bound type parameter does not work when type argument is not specified explicitly当未明确指定类型参数时,Scala 下限类型参数不起作用
【发布时间】:2019-11-16 16:05:39
【问题描述】:

我有一个下面的类,它使用协方差注释和另一个类型参数作为它的方法,类类型参数是下限

class MyQueue[+T]{
  def add[U >: T](arg:U):Unit= {
    println("Arg value :"+ arg)
  }
}

鉴于上面的代码,我不明白为什么下面的行会成功执行。根据我对下限的理解,方法“add”应该只接受 Int 类型或其超类型的值。

val q1:MyQueue[Int] = new MyQueue[Int]
q1.add("string")

但是,如果我们如下明确指定类型参数,它会给出预期的编译错误(字符串不符合方法 add 的类型参数边界)

q1.add[String]("string")

【问题讨论】:

    标签: scala covariance type-parameter type-bounds


    【解决方案1】:

    String 不是Int 的超类型,但IntString 之间共享一个公共超类型,即Any

    val q1:MyQueue[Int] = new MyQueue[Int]
    q1.add("string")
    

    等价于

    val q1:MyQueue[Int] = new MyQueue[Int]
    q1.add[Any]("string")
    

    另一方面,如果您将String 作为类型参数显式传递,则会发生编译错误,因为String 不是Int 的超类型

    【讨论】:

      【解决方案2】:

      我将添加到 @MikelSanVicente 的答案中,如果您希望 q1.add("string") 不编译,您应该将类​​型绑定替换为隐式类型约束

      class MyQueue[+T]{
        def add[U](arg: U)(implicit ev: T <:< U): Unit= {
          println("Arg value :"+ arg)
        }
      }
      
      val q1: MyQueue[Int] = new MyQueue[Int]
      q1.add("string") // doesn't compile
      
      q1.add[String]("string") // doesn't compile
      
      q1.add[Any]("string") // compiles
      

      https://blog.bruchez.name/2015/11/generalized-type-constraints-in-scala.html

      【讨论】:

        猜你喜欢
        • 2019-02-14
        • 1970-01-01
        • 2021-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-05
        相关资源
        最近更新 更多