Scala pattern matching in generic type with TypeTag generates warning, but ClassTag doesn't?

I have two very similar methods. The only difference is the use of ClassTag and TypeTag :

 def matchClass[A: ClassTag](v: Any) = v match { case a: A => "it A" case _ => "not A" } def matchType[A: TypeTag](v: Any) = ... // same code as matchClass 

A compilation warning will be displayed for matchType , but not for matchClass :
abstract type pattern A is unchecked since it is eliminated by erasure case a: A

Why is there a warning? Why is it displayed only for TypeTag and not ClassTag ?

+3
source share
1 answer

You do not see a warning for classTag , because this check just works for them:

 scala> matchClass[Int]("aaa") res82: String = not A scala> matchClass[Int](5) res83: String = it A 

And does not work for typeTag :

 scala> matchType[Int](5) res84: String = it A scala> matchType[Int]("aaa") res85: String = it A 

The reason is that to match patterns in classTags (when it sees an implicit), the compiler generates something like:

 case a: A if classTag[A].runtimeClass.isInstance(a) => ... 

There is no way to get runtimeClass for typeTag in general, so why this does not apply to them. Pattern matching cannot match typical (polymorphic) types due to erasure, so you can see this warning by default:

  scala> def matchGeneric[A](v: Any) = | v match { | case a: A => "it A" | case _ => "not A" | } <console>:28: warning: abstract type pattern A is unchecked since it is eliminated by erasure case a: A => "it A" ^ matchGeneric: [A](v: Any)String 

UPDATE: since @Seth Tisue mentioned when a tag comes from the universal version at runtime, you can get a runtime class for it (but you need to create a mirror first).

+7
source

Source: https://habr.com/ru/post/1258661/


All Articles