加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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的对象时,这些建议才有帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读