Pattern matching around type erasure

本文介绍如何解决Scala中因类型擦除导致的模式匹配警告,并提供使用自定义提取器来区分泛型实例类型的代码示例。

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值