If I want to avoid the isInstanceOf & asInstanceOf combo, and instead want to use pattern matching, is there any simple way to avoid the erasure problem in the following example? I researched some answers but they all seem to use Manifest and the resulting code looked more complex than the undesirable isInstanceOf & asInstanceOf combo.

trait Comparable[A] extends Ordered[A] {
  override def equals(that : Any) = 
    that match {
      case that : A => compare(that) == 0
      case _ => false
    }
}

My goal in the code above is to create a single trait that adds implementation for == and != to the ordered comparators. However, I get the following error because A gets erased:

warning: abstract type pattern A is unchecked since it is eliminated by erasure
      case that : A => compare(that) == 0

NOTE: there are other similar questions on StackOverflow regarding this issue, but the accepted answers seem to use Manifest, hence my question - can this be achieved in a simpler way?

有帮助吗?

解决方案

No, there is no simpler way. Manifest has been replaced by ClassTag and TypeTag, but there isn't any easy way to get the needed ClassTag - traits can't take parameters, and equals in Any wasn't declared to take an implicit ClassTag, so we have to force the implementing class to provide it:

import scala.reflect.ClassTag

trait Comparable[A] extends Ordered[A] {
  implicit def ct: ClassTag[A]

  override def equals(that: Any) = 
    that match {
      case that: A => compare(that) == 0
      case _ => false
    }
}

isInstanceOf won't help either, it will still require the ClassTag.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top