Тип Scala обобщает расширяемый интерфейс - PullRequest
0 голосов
/ 10 июня 2019

Отлично работает следующий 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 [T]] </p>

На самом деле класс B также имеет член сравнения. Как я могу изменить определение класса C, чтобы сделать его совместимым с классом B? Спасибо!

Ответы [ 2 ]

2 голосов
/ 10 июня 2019

Рассмотрим альтернативную реализацию, используя 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
1 голос
/ 10 июня 2019

Поскольку B расширяется Comparable[A], а не Comparable[B].Но это не соответствует T <: Comparable[T] (потому что B <: Comparable[B] не соответствует действительности).

Следующий код работает нормально:

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