Scala 2.10 TypeTag 用法

2024-01-04

我正在挖掘新的 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))

Question。我正在使用吗TypeTag错误还是新反射API的缺陷?

PS0。尝试过Scala 2.10.0-RC1 and 2.10.0-RC2

PS1。解决方法是更换TypeTag with Manifest,所以用下面的代码collect按顺序将返回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]
}

Update: 和新的一样Scala 2.10.0-RC2发布。


所以我认为这里的关键问题是你需要匹配类型msg,但它的编译时类型是Any(来自PartialFunction宣言)。本质上,你想要一个不同的TypeTag对于你的每个元素List[Any]。但由于它们都有编译时类型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, "hello", Foo(1), List(1), List("a"))
messages collect new TFilter[Foo].f // produces List(Foo(1))

As 阿吉兰指出 https://stackoverflow.com/a/13234888/384641,就像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 https://issues.scala-lang.org/browse/SI-6517),但我认为只有当您与具有有用的对象进行匹配时,这些才会有帮助TypeTag,不是编译时类型为Any.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 2.10 TypeTag 用法 的相关文章

随机推荐

  • 设置/更改 iFrame 的 MIME 类型?

    是否可以使用 JavaScript 动态设置 iFrame 的 MIME 类型 DIV 有同样的问题吗 No MIME 类型由您加载的内容决定 对于一个无论什么框架src指定 Div 不加载外部内容 因此没有 MIME 类型
  • 如何设置 SPAN 的高度属性

    我需要使以下代码可拉伸并具有预定义的高度 span class title This is title span 但是由于span是内联元素 height 属性不起作用 我尝试使用div相反 它会扩展到上部元素的宽度 并且宽度要灵活 对此有
  • 如何在 Laravel 5 表单中使用 Markdown 作为文本区域输入字段?

    在我的基于 Laravel 5 的项目中 我使用的是 Markdown 包http packalyst com packages package graham campbell markdown http packalyst com pac
  • Python Sphinx 锚点在任意线上

    如何使用 Sphinx 在 ReST 中的任意行设置锚点引用 为了更清楚 这里有一个例子 A title with an anchor some stuff 这将创建一个标题A title with an anchor并添加一个额外的on
  • 如何为 CSS 垂直下拉菜单添加延迟

    我需要为下拉菜单的鼠标悬停事件添加延迟 这样如果有人将鼠标悬停在菜单上并转到页面上的另一个链接 菜单不会立即下拉 感谢您的帮助 http jsfiddle net cgagliardi NPVVQ http jsfiddle net cga
  • saltstack jinja 中的“json”和“tojson”过滤器有什么区别吗?

    根据 saltstack 文档 它是 json https docs saltstack com en latest ref renderers all salt renderers jinja html https docs saltst
  • 在字典中循环

    我用这个 foreach KeyValuePair
  • 过滤查询以填充 FirebaseRecyclerAdapter

    目前尚不清楚如何使用自定义查询填充 FirebaseRecyclerAdapter 定义一个参考 这里 DatabaseReference ref mDatabase getReference child users 将其发送到适配器 in
  • 保护HTML5游戏来源

    人们对 HTML5 赞不绝口 但我主要关心的问题之一是如何保护我的游戏源代码 本质上 如何防止别人使用我们自己开发的游戏引擎 那是一笔巨大的资产 如何防止他人下载游戏并将其托管在其他平台 如何隐藏源中的服务器 API 调用详细信息 例如我们
  • Ruby 相当于 PHP 的 ucfirst() 函数

    在 Ruby 使用 Rails 如果相关的话 中将字符串的第一个字母大写的最佳方法是什么 注意String capitalize不是我想要的 因为除了将字符串的第一个字母大写之外 此函数还使所有其他字符小写 我不想要 我想保持它们不变 gt
  • 如何在 bash 脚本中获取文件的第一行?

    我必须在文件的第一行放入 bash 变量 我猜是用grep命令 但是有什么方法可以限制行数吗 head从文件中获取第一行 然后 n参数可用于指定应提取多少行 line head n 1 filename
  • 尝试使用 conda 时出现“语法错误:生成器表达式必须带括号”

    每当我尝试访问任何 anaconda 命令时 我都会遇到这个问题 事实上 当我尝试打开我的虚拟环境时 它也显示在那里 我已经重新安装了 anaconda navigator 但仍然没有结果 C Users Gagan Singh gt ac
  • 如何通过 holoviz 和 NetworkX 渲染 GraphViz Dot 文件?

    所以我看着docs https hvplot holoviz org user guide NetworkX html并看到他们使用 Graphviz 但不使用任何文件 而且我有一个4mil dot 70mb 图形文件 https gith
  • 在 Ubuntu 上找不到 RODBC 包中的 odbcConnectExcel 函数

    在 Ubuntu 上安装 RODBC 包有点麻烦 首先我学会了安装以下内容 sudo apt get install r cran rodbc 这还不够好 因为包仍在寻找头文件 我通过以下方式解决了这个问题 sudo apt get ins
  • 导出或保存 CX509PrivateKey

    是否可以以某种方式保存或导出CX509PrivateKey 我的想法是 我创建一个 CSR 发送给 CA 获取证书 然后 不知何故我必须获取私钥 但不知道如何获取 不幸的是在谷歌上没有找到任何内容 我的一段代码 var objPrivate
  • SQL INSERT 不指定列。会发生什么?

    在浏览心爱的 W3schools 时发现了这个page http www w3schools com sql sql insert asp并且实际上学到了一些有趣的东西 我不知道您可以调用插入命令而不指定值的列 例如 INSERT INTO
  • 使用jquery删除字符串中的span标签

    如何使用jquery从字符串中删除span标签 我在字符串变量中有多个跨度标签 p No Change span style color 222222 nbsp span I love cricket span style color 22
  • 满足条件后避免使用 IF 语句

    我在一个重复多次的循环内进行除法运算 碰巧的是 在循环的前几次 或多或少的前 10 个循环 中 除数为零 一旦它获得价值 除零误差就不再可能 我有一个if测试除数值的条件以避免 div 为零 但我想知道评估此值会对性能产生影响if在后续循环
  • Android 开发人员通常在 iPhone 上使用第三方 UI/网络库(例如 Three20)吗?

    我做过很多 iPhone 方面的工作 但从来没有做过 Android 方面的工作 在 iPhone 上 几个月后我发现了 Three20 库 非常棒 并开始移动我的代码 我不想在转向 Android 时犯同样的错误 所以我的问题是 Andr
  • Scala 2.10 TypeTag 用法

    我正在挖掘新的 scala 反射 api 但无法弄清楚为什么以下代码片段不能按预期工作 给定层次结构 尽力简化 import scala reflect runtime universe trait TF A implicit def t