Scala isInstanceOf[T] 函数无法使用有界 ClassTag/TypeTag
Scala isInstanceOf[T] function fail to use bounded ClassTag/TypeTag
代码如下:
abstract class Foo[T: ClassTag] {
def v(a: Any): Any = a match {
case _ if a.isInstanceOf[T] => Some(a)
case _ => None
}
}
在编译中产生以下内容:
Warning: abstract type T is unchecked since it is eliminated by erasure
case _ if a.isInstanceOf[T] =>
奇怪的是,大小写匹配会按预期工作。有没有办法让 isInstanceOf[T] 也知道 ClassTag 上下文绑定?
我不会说这是按预期工作的:
scala> (new Foo[String] {}).v(List(1))
res10: Any = Some(List(1)) // Not a String!
不要使用 isInstanceOf
,因为它根本不使用 ClassTag
。您可以使用 ClassTag
提取器,而不是:
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)
这都是语法糖:
abstract class Foo[T](implicit ct: ClassTag[T]) {
def v(a: Any) = a match {
case ct(a) => Some(a)
case _ => None
}
}
代码如下:
abstract class Foo[T: ClassTag] {
def v(a: Any): Any = a match {
case _ if a.isInstanceOf[T] => Some(a)
case _ => None
}
}
在编译中产生以下内容:
Warning: abstract type T is unchecked since it is eliminated by erasure
case _ if a.isInstanceOf[T] =>
奇怪的是,大小写匹配会按预期工作。有没有办法让 isInstanceOf[T] 也知道 ClassTag 上下文绑定?
我不会说这是按预期工作的:
scala> (new Foo[String] {}).v(List(1))
res10: Any = Some(List(1)) // Not a String!
不要使用 isInstanceOf
,因为它根本不使用 ClassTag
。您可以使用 ClassTag
提取器,而不是:
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)
这都是语法糖:
abstract class Foo[T](implicit ct: ClassTag[T]) {
def v(a: Any) = a match {
case ct(a) => Some(a)
case _ => None
}
}