scalacontext-bound

Scala isInstanceOf[T] function fail to use bounded ClassTag/TypeTag


The follow code:

abstract class Foo[T: ClassTag] {
    def v(a: Any): Any = a match {
        case _ if a.isInstanceOf[T] => Some(a)
        case _ => None
    }
}

yield the following in compilation:

Warning: abstract type T is unchecked since it is eliminated by erasure
    case _ if a.isInstanceOf[T] =>

Strangely, case match will work as intended. Is there a way to make isInstanceOf[T] be aware of the ClassTag context bound as well?


Solution

  • I wouldn't say this is working as expected:

    scala> (new Foo[String] {}).v(List(1))
    res10: Any = Some(List(1)) // Not a String!
    

    Don't use isInstanceOf, as it doesn't use ClassTags at all. You can use the ClassTag extractor, instead:

    abstract class Foo[T: ClassTag] {
        def v(a: Any) = a match {
            case _: T => Some(a)
            case _ => None
        }
    }
    
    scala> (new Foo[String] {}).v(1)
    res3: Option[Any] = None
    
    scala> (new Foo[String] {}).v("abc")
    res4: Option[Any] = Some(abc)
    

    This is all syntactic sugar for:

    abstract class Foo[T](implicit ct: ClassTag[T]) {
        def v(a: Any) = a match {
            case ct(a) => Some(a)
            case _ => None
        }
    }