Scala 2.10 TypeTag的用法
发布时间:2020-12-16 19:06:33 所属栏目:安全 来源:网络整理
导读:我正在挖掘新的 scala反射api,不知道为什么以下代码段不能按预期工作.给定层次结构(尽可能简化): import scala.reflect.runtime.universe._trait TF[A] { implicit def t: TypeTag[A] def f[T : A: TypeTag]: PartialFunction[Any,A] = { case msg: T if ty
我正在挖掘新的
scala反射api,不知道为什么以下代码段不能按预期工作.给定层次结构(尽可能简化):
import scala.reflect.runtime.universe._ trait TF[A] { implicit def t: TypeTag[A] def f[T <: A: TypeTag]: PartialFunction[Any,A] = { case msg: T if typeOf[T] =:= typeOf[A] => msg } } class TFilter[T: TypeTag] extends TF[T] { def t = typeTag[T] } case class Foo(x: Int) 我期望方法f过滤给定类型的对象.所以下面的代码片段应该返回Seq [Foo] val messages = Seq(1,"hello",Foo(1)) val tFilter = new TFilter[Foo] messages collect tFilter.f[Foo] 它实际上返回Seq [Foo],但其他消息未被过滤,这听起来像一个错误. res1: Seq[Foo] = List(1,hello,Foo(1)) 题.我使用TypeTag错误还是新的反射api的缺陷? PS0.试用了Scala 2.10.0-RC1和2.10.0-RC2 PS1.解决方法是用Manifest替换TypeTag,所以使用以下代码收集序列将按预期返回List(Foo(1)). trait MF[A] { implicit def m: Manifest[A] def f[T <: A: Manifest]: PartialFunction[Any,A] = { case msg: T if typeOf[T] =:= typeOf[A] => msg } } class MFilter[T: Manifest] extends MF[T] { def m = manifest[T] } 更新:与新的Scala 2.10.0-RC2版本相同. 解决方法
所以我认为这里的关键问题是你需要匹配msg的类型,但它的编译时类型是Any(来自PartialFunction声明).实际上,您希望为List [Any]中的每个元素使用不同的TypeTag.但是由于它们都具有编译时类型为Any,因为它们都被放在同一个列表中,所以你不会得到一个比此更具体的TypeTag.
我想你可能想要做的是使用ClassTag而不是TypeTag: trait TF[A] { implicit def t: ClassTag[A] def f: PartialFunction[Any,A] = { case msg: A => msg } } class TFilter[T: ClassTag] extends TF[T] { def t = classTag[T] } case class Foo(x: Int) val messages = Seq(1,Foo(1),List(1),List("a")) messages collect new TFilter[Foo].f // produces List(Foo(1)) 作为Ajran points out,就像Manifest版本一样,您必须了解运行时类型的所有限制,包括擦除和拳击问题: messages collect new TFilter[List[Int]].f // produces List(List(1),List("a")) messages collect new TFilter[Int].f // produces List() messages collect new TFilter[java.lang.Integer].f // produces List(1) 有一些关于如何使TypeTag对模式匹配(例如SI-6517)更有用的建议,但是我认为只有当您使用有用的TypeTag匹配对象,而不是使用编译时类型为Any的对象时,这些建议才有帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |