【问题标题】:Scala generics type extends Comparable interfaceScala 泛型类型扩展了 Comparable 接口
【发布时间】:2019-06-10 16:04:30
【问题描述】:

以下 scala 代码可以正常工作:

class A(val value : Int) extends Comparable[A]
{
    override def compareTo(o: A): Int = this.value.compareTo(o.value)
}

class B(value : Int) extends A(value)

class C[T <: Comparable[T]](val value : T) extends Comparable[C[T]]
{
    override def compareTo(o: C[T]): Int = value.compareTo(o.value)
}

val a1 = new A(1)
val a2 = new A(2)
println(a1.compareTo(a2))

val b1 = new B(1)
val b2 = new B(2)
println(b1.compareTo(b2))

val ac1 = new C[A](a1)
val ac2 = new C[A](a2)
println(ac1.compareTo(ac2))

但是下一个编译出错:

val bc1 = new C[B](b1)
val bc2 = new C[B](b2)
println(bc1.compareTo(bc2))

错误:类型参数 [B] 不符合 C 类的类型参数界限 [T <: comparable>

实际上 B 类也有一个 compareTo 成员。如何更改 C 类的定义以使其与 B 类兼容?谢谢!

【问题讨论】:

    标签: scala generics f-bounded-polymorphism


    【解决方案1】:

    考虑使用Ordering 类型类的替代实现

    class A(val value: Int)
    class B(value: Int) extends A(value)
    
    class C[T](val value: T)
    
    implicit val aOrdering = new Ordering[A] {
      def compare(a1: A, a2: A): Int = a1.value compare a2.value
    }
    
    implicit val bOrdering = new Ordering[B] {
      def compare(b1: B, b2: B): Int = b1.value compare b2.value
    }
    
    implicit class CompareToA[T <: A](`this`: T) {
      def compareTo(that: T)(implicit o: Ordering[T]): Int = o.compare(`this`, that)
    }
    
    implicit class CompareToC[T](`this`: C[T]) {
      def compareTo(that: C[T])(implicit o: Ordering[T]): Int = o.compare(`this`.value, that.value)
    }
    

    哪个输出

    val b1 = new B(1)
    val b2 = new B(2)
    val bc1 = new C[B](b1)
    val bc2 = new C[B](b2)
    bc1.compareTo(bc2) // res3: Int = -1
    

    【讨论】:

      【解决方案2】:

      因为B 扩展了Comparable[A],而不是Comparable[B]。它与T &lt;: Comparable[T] 不匹配(因为B &lt;: Comparable[B] 不正确)。

      以下代码可以正常工作:

      val bc1 = new C[A](b1)
      val bc2 = new C[A](b2)
      println(bc1.compareTo(bc2))
      

      【讨论】:

      • 谢谢!这个答案解释了我的问题。马里奥的回答对我的项目来说更方便,所以我选择了。
      猜你喜欢
      • 1970-01-01
      • 2017-12-07
      • 2011-01-14
      • 2015-04-01
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多