简体   繁体   中英

Scala TypeTag doesn't prevent from Type Erasure

In this thread, I'm writing a simple helper function for TraversableLike:

How to specify a type parameter in calling a function while let the compiler infer the other?

I implement the following function:

  implicit class TraversableLikeView[A, Repr](self: TraversableLike[A, Repr]) {

    def filterByType[B: TypeTag] = new FilterByType[B]

    class FilterByType[B: TypeTag] {

      def get[That](implicit bf: CanBuildFrom[Repr, B, That]): That = {
        val result = self.flatMap{
          v =>
            val unboxed = Utils.javaUnbox(v)
            unboxed match {
              case x: B => Some(x)
              case _ => None
            }
        }(bf)
        result
      }
    }
  }

The TypeTag is used since ClassTag.unapply had some problem in handling primitive classes. However, when I compile the above code I got the following warning:

Warning:(304, 23) abstract type pattern B is unchecked since it is eliminated by erasure
              case x: B => Some(x)
                      ^

Which is against what TypeTag claim to do (ClassTag was doing an almost perfect job here). Is there a reason why TypeTag fail in this case?

This is only supported by ClassTag , because you can get a Class from it and you can't in general get a Class from a TypeTag : eg in macros the class isn't compiled yet. But presumably you are using scala.reflect.runtime.universe.TypeTag , in which case you can write

implicit val classTagB = ClassTag[B](mirror.runtimeClass(typeTag[B].tpe))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM