You may have encountered this warning: "scala non-variable type argument in type pattern is unchecked since it is eliminated by erasure". If you google for it, you quickly find several decent Stack Overflow and forum replies that will suggest you to structure your code differently or use Type Manifests. They may even mention that there is an option to write custom extractor, but most of the time without transparent code sample. I decided to write this post to give such an easy-to-grasp code snippet.
Let's prepare the scene. Assume we have some generic class, which actual instance type will be erased.
class Container[T](data: T) {
def get = data
}
// Let's simulate type erasure, otherwise Scala compiler will
// figure out the type. It is really that smart :)
def stored: Container[_] = new Container("hello")
Next, our straightforward pattern match may work in some cases, but will generate a warning and will not be able to distinguish for the type of the generic:
stored match {
case c: Container[String] => println(c.get)
// The second condition will never be executed
case c: Container[Int] => println("Int " + c.get)
}
But it is very easy to create an extractor object:
object Container {
def unapply[T](x: Container[T]) = Some(x.get)
}
Now you can use it hassle-free:
stored match {
case Container(data: String) => println(data)
case Container(data: Int) => println("Int " + data)
}
But what if you want to match on a type of generic, but still have the entire container object, not its content? That is simple as well:
stored match {
// "x" will be the entire container
case x @ Container(_: String) => println(x)
case x @ Container(_: Int) => println("Int " + x)
}
This functionality is well documented and is safe to be used.
本文介绍如何解决Scala中因类型擦除导致的模式匹配警告,并提供使用自定义提取器来区分泛型实例类型的代码示例。


被折叠的 条评论
为什么被折叠?



