Scala 宏:“无法从具有未解析类型参数的类型 T 创建 TypeTag”

2023-11-24

我正在玩 Scala 新宏并发现了这个gist from akshaal。看起来我不太明白。 鉴于以下特征(fieldsMacro 或多或少与 akshaal 示例中的相同)

case class Field[I <: AnyRef](name: String, get: I => Any)

type Fields[I <: AnyRef] = List[Field[I]]

trait FieldAccess {
import FieldMacors._
    import Field._
    import language.experimental.macros

    def fields[T <: AnyRef]: Fields[T] = macro fieldsMacro[T]

    def field[T <: AnyRef](name: String): Fields[T] = fields[T].headOption <-- does not work!
                                                             ^
}
 object FieldMacors {

import language.experimental.macros
import Field._

def fields[T <: AnyRef]: Fields[T] = macro fieldsMacro[T]

/**
 * Get a list of fiels
 */
def fieldsMacro[T <: AnyRef: c.TypeTag](c: Context): c.Expr[Fields[T]] = {
  import c.universe._
  val instanceT = c.typeOf[T]

  val fields = instanceT.members.filter(member => member.isTerm && !member.isMethod)

  // transform an iterable of expr in a expr of list.
  def foldIntoListExpr[T: c.TypeTag](exprs: Iterable[c.Expr[T]]): c.Expr[List[T]] =
    exprs.foldLeft(reify { Nil: List[T] }) {
      (accumExpr, expr) =>
        reify { expr.splice :: accumExpr.splice }
    }

  val fieldAccessores = for (field <- fields) yield {
    val name = field.name.toString.trim // Why is there a space at the end of field name?!
    val nameExpr = c literal name

    // Construct expression (x : $I) => x.$name
    val getFunArgTree = ValDef(Modifiers(), newTermName("x"), TypeTree(instanceT), EmptyTree)
    val getFunBodyTree = Select(Ident(newTermName("x")), newTermName(name))
    val getFunExpr = c.Expr[T => Any](Function(List(getFunArgTree), getFunBodyTree))
    reify {
      Field[T](name = nameExpr.splice, get = getFunExpr.splice)
    }
  }
  foldIntoListExpr(fieldAccessores)
}
}

编译器抱怨 “无法从具有未解析类型参数的类型 T 创建 TypeTag”

我如何设法让 T 进入宏或者我必须实现另一个使用 fieldsMacro 的宏


T: TypeTag类型参数的上下文绑定T意味着您需要提供具体的类型参数来代替此参数(即不包含对未标记类型参数或抽象类型成员的引用)。否则会发生错误。

例子:

scala> val ru = scala.reflect.runtime.universe
ru @ 6d657803: scala.reflect.api.JavaUniverse = scala.reflect.runtime.JavaUniverse@6d657803

scala> def foo[T: ru.TypeTag] = implicitly[ru.TypeTag[T]]
foo: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]

scala> foo[Int]
res0 @ 7eeb8007: reflect.runtime.universe.TypeTag[Int] = TypeTag[Int]

scala> foo[List[Int]]
res1 @ 7d53ccbe: reflect.runtime.universe.TypeTag[List[Int]] = TypeTag[scala.List[Int]]

scala> def bar[T] = foo[T] // T is not a concrete type here, hence the error
<console>:26: error: No TypeTag available for T
       def bar[T] = foo[T]
                       ^

scala> def bar[T] = foo[List[T]] // T being not concrete renders 
                                 // the entire compound type not concrete
<console>:26: error: No TypeTag available for List[T]
       def bar[T] = foo[List[T]]
                       ^

scala> def bar[T: TypeTag] = foo[T] // to the contrast T is concrete here
                                    // because it's bound by a concrete tag bound
bar: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]

scala> bar[Int]
res2 @ 7eeb8007: reflect.runtime.universe.TypeTag[Int] = TypeTag[Int]

scala> def bar[T: TypeTag] = foo[List[T]]
bar: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[List[T]]

scala> bar[Int]
res3 @ 1a108c98: reflect.runtime.universe.TypeTag[List[Int]] = TypeTag[scala.List[Int]]

scala> bar[List[Int]]
res4 @ 76d5989c: reflect.runtime.universe.TypeTag[List[List[Int]]] = TypeTag[scala.List[scala.List[Int]]]

拥有在编译时强制执行的具体类型的概念是很有用的。默认情况下启用具体类型标签很有用,并且在https://issues.scala-lang.org/browse/SI-5884.

然而,正如您所看到的,宏中的具体类型标记可能会造成混乱,因为通常宏应该适用于具体类型和非具体类型。因此人们应该始终使用c.AbsTypeTag反而。由于这个原因,我们不再允许c.TypeTag2.10.0-M7 中的上下文边界:https://github.com/scala/scala/commit/788478d3ab.

Edit。在2.10.0-RC1中一些AbsTypeTag已更名为WeakTypeTag。有关类型标签的其他所有内容都保持不变。

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

Scala 宏:“无法从具有未解析类型参数的类型 T 创建 TypeTag” 的相关文章

  • Xcode 在调试版本中是否有自动设置的宏?

    所以我可以写这样的代码 ifdef whatever do stuff that will never show up in the production version endif 默认情况下没有什么用处 但您可以设置DEBUG用于调试构
  • Scala中如何将DataFrame转换为RDD?

    有人可以分享一下如何转换dataframe to an RDD Simply val rows RDD Row df rdd
  • Spark - Scala - 用另一个数据帧中的查找值替换数据帧中的值

    我正在 Databricks 上使用 Spark 编程语言是Scala 我有两个数据框 主要数据框 见截图 1 https i stack imgur com EShir png 查找数据框 见截图3 https i stack imgur
  • Spark:用列的平均值替换数据框中的空值

    如何创建 UDF 以编程方式将每列中 Spark 数据框中的空值替换为列平均值 例如 在示例中 数据 col1 空值的值为 2 4 6 8 5 5 5 示例数据 col1 col2 col3 2 null 3 4 3 3 6 5 null
  • IntelliJ IDEA Scala 插件问题

    我对新的 Intellij IDEA 10 和 Scala 插件有疑问 当我在 Scala 源文件中输入任何内容时 编辑器会永久冻结 在其他文件 java 和其他 编辑器中效果很好 结构视图 scala 检查和显示成员功能已关闭 堆大小增加
  • 如何检查字符串中是否包含某个字符?

    我想检查字符串是否包含该字符 我正在编写一个刽子手代码 例如 下面是要猜测的单词 scala 但看起来像 至用户 假设用户输入字母 a 那么它一定看起来像 a a def checkGuess if result contains user
  • 哪些 ORM 与 Scala 配合得很好? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Spark RDD默认分区数

    版本 Spark 1 6 2 Scala 2 10 我正在执行以下命令spark shell 我试图查看 Spark 默认创建的分区数量 val rdd1 sc parallelize 1 to 10 println rdd1 getNum
  • 重塑案例类构造函数?

    试图找到一种方法来 重塑 案例构造函数以填充某些默认值 以下情况可能吗 def reshape T R1 lt HList R2 lt HList h R1 R2 gt T example case class MyClass a Doub
  • 如何抑制spark输出控制台中的“Stage 2===>”?

    我有数据帧并试图获取不同的计数并且能够成功获取不同的计数 但是每当 scala 程序执行时我都会收到此消息 Stage 2 gt 1 1 2 我如何在控制台中抑制特定的此消息 val countID dataDF select substr
  • 一次性的 lisp 宏,我的实现正确吗?

    我正在尝试从 Peter Seibel 的书 Practical Common Lisp 中学习 Lisp 在第 8 章 宏 定义你自己的 http www gigamonkeys com book macros defining your
  • 有没有办法捕获 Spark 中使用通配符读取的多个 parquet 文件的输入文件名?

    我使用 Spark 将多个 parquet 文件读取到单个 RDD 中 并使用标准通配符路径约定 换句话说 我正在做这样的事情 val myRdd spark read parquet s3 my bucket my folder parq
  • 如何从 SparkSQL DataFrame 中的 MapType 列获取键和值

    我的镶木地板文件中有数据 该文件有 2 个字段 object id String and alpha Map lt gt 它被读入 SparkSQL 中的数据帧 其架构如下所示 scala gt alphaDF printSchema ro
  • 如何发现 Scala 远程 Actor 已死亡?

    在 Scala 中 当另一个 远程 actor 终止时 可以通过设置 trapExit 标志并以第二个 actor 作为参数调用 link 方法来通知一个 actor 在这种情况下 当远程参与者通过调用 exit 结束其工作时 第一个参与者
  • 阶乘的 Scala 排列

    我怎样才能找到n Scala 中某些字母的排列 Scala 2 9 RC1 scala gt abc permutations toList res58 List String List abc acb bac bca cab cba
  • 使用 Spray-json 解析简单数组

    我正在尝试 但失败了 了解 Spray json 如何将 json feed 转换为对象 如果我有一个简单的 key gt value json feed 那么它似乎可以正常工作 但是我想要读取的数据出现在如下列表中 name John a
  • Scala 如何忽略 Java 的检查异常?

    例如如果调用 JavaThread sleep这会抛出一个已检查的InterruptedException来自 Scala 源文件 然后不需要将调用包含在 Scala 中try catch Scala 如何删除将调用包围在 a 中的规则tr
  • Java 表达式树 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有相当于 net的 LINQ 下的表达式树JVM 我想实现一些类似 LINQ 的代码结构Scala
  • 使用 Spark DataFrame 获取组后所有组的 TopN

    我有一个 Spark SQL DataFrame user1 item1 rating1 user1 item2 rating2 user1 item3 rating3 user2 item1 rating4 如何按用户分组然后返回TopN
  • Scala Tuple2Zipped 与 IterableLike zip

    两种实现有什么区别 这个比那个好吗 有一篇博客文章说 Tuple2Zipped 性能更好 但没有提供原因 并且查看源代码我没有看到差异 val l1 List 1 2 3 val l2 List 5 6 7 val v1 l1 zip l2

随机推荐

  • targetNamespace 和 xmlns

    这一页w3学校给出 以下是模式声明的一种形式
  • 错误:使用无法解析的标识符“kCGBlendModeMultiply”

    我最近更新到了 Xcode 7 beta 3 我遇到了一些问题 我似乎找不到任何问题 当我运行我的应用程序时 我收到 3 个错误 使用未解析的标识符 kCGBlendModeMultiply 使用未解析的标识符 kCGLineCapRoun
  • Java 相当于 C++ std::map?

    我正在寻找一个具有 C std map 通常实现特征的 Java 类 据我所知 是一个自平衡二叉搜索树 插入 删除 搜索的 O log n 性能 每个元素由唯一的键和映射的值组成 键遵循严格的弱排序 我正在寻找开源或设计文档的实现 我可能最
  • Tomcat 7 中的表达式语言跳过标识符检查

    我收到以下错误 SEVERE Servlet service for servlet jsp threw exception javax el ELException The identifier case is not a valid J
  • Spring中的自动配置重新初始化

    在 Log4j 中 有一个功能可以将系统初始化为按时间间隔进行配置和监视 这允许 log4j 系统在属性文件更改时重新加载其属性 spring框架是否有这样的配置观察器设施 其中配置更改时会重新加载 需要重新加载的Configuration
  • Discord.js - 获取用户上次活动?

    我试图找出是否可以使用追溯方式获取用户上次活动的时间 信息discord js 说我有类似的东西 client guilds find id SERVER ID fetchMembers then members gt const role
  • 如何更改videojs控制栏元素顺序的位置

    我的网站使用 video js 播放器 我想更改控制栏元素的位置 目前 它显示播放 暂停 音量 进度条和全屏 我怎样才能更改订单 我的代码如下 var videojs videojs video player techOrder youtu
  • 如何阻止软键盘调整 Android 手机上 Chrome 浏览器窗口的大小?

    我看到这个问题被问到here here and here 但找不到明确和 或可行的答案 我在 Samsung A7 2018 上使用 Android 9 运行 Chrome 75 会发生什么 我有一个需要键盘输入的 html 表单 当在 C
  • JBoss 文件打开过多错误

    就在上周 我在访问 JBoss v 4 2 2 Web 应用程序时遇到了问题 当我转到主页时 我收到 java lang NullPointerException 错误页面 查看 JBoss 日志输出后 似乎打开了太多文件 那么我该如何关闭
  • 读取 Unicode 文件 C++

    我有一个简单的问题要问 我有一个以 FFFE 开头的 UTF 16 文本文件要读取 有哪些C 工具可以处理这种文件 我只想阅读它 过滤一些行 然后显示结果 它看起来很简单 但我只有处理普通 ascci 文件的经验 而且我很着急 我正在使用
  • 同步单例的正确使用?

    所以我正在考虑建立一个业余爱好项目 这是一种临时性的事情 只是为了温习我的编程 设计 它基本上是一个多线程网络蜘蛛 更新相同的数据结构object gt int 因此 为此使用数据库绝对是大材小用 我唯一能想到的是用于包含我的数据结构的线程
  • mysql:使用SET还是很多列?

    我正在使用 PHP 和 MySQL 我有以下记录 具有各种分层 事件类型 的事件 事件可以有多个类别和子类别 但此类类别和子类别的数量是固定的 带时间戳 设置桌子的最佳方式是什么 我是否应该有一堆列 30 左右 其中包含表示是或否的枚举 指
  • 如何递归地查找模块中的所有模块和类?

    如果你有 module A class B end end 您可以通过 A constants 找到 B 和类似的类 但是 在 Ruby 1 9 3 中 如果 B 在另一个模块中 则无法获取 B 在 Ruby 1 8 7 中您可以 modu
  • UI布局初始化错误-center-pane元素不存在

    我正在使用具有 centerLayout westLayout northLayout 的布局结构 当我运行该文件时 出现以下错误 UI 布局初始化错误 中心窗格元素不存在 中心窗格是必需的元素 我的模板是
  • Flutter 问题:滚动时列表视图重建项目

    当我滚动到列表视图的底部时 底部的项目将被重建 同样 当我滚动到顶部时 我的第一个项目会被重建 第一个项目是一张带有可选筹码的卡片 当发生这种情况时 该筹码将被取消选择 入口 动画也会重播 我怎样才能阻止这个 这是基本代码 它使用 simp
  • 如何修复NoSuchMethodError?

    我使用 Scala 2 10 0RC1 和 sbt 0 12 1 是什么原因导致此运行时错误以及如何修复此错误 在 2 9 2 上运行良好 确切的错误消息是 java lang NoSuchMethodError scala Predef
  • 如何使用 ScalaMock 模拟按名称调用参数(如 getOrElse)?

    我希望能够模拟返回值getOrElse方法 以便它返回传递的内容orElseScalaMock 的按名称调用参数 trait ToBeMocked def getOrElse arg Int orElse gt String String
  • 向测试厨房添加属性

    我正在尝试覆盖中的属性java食谱与测试厨房 当我尝试跑步时kitchen converge default centos 64 出现严重的 YAML 错误 driver name vagrant customize memory 1024
  • Angular4x:带有过期参数的 ngx-cookie-service

    我正在使用 ngx cookie service 组件 但是一旦我关闭浏览器 cookie 就会消失 也许我必须设置过期参数 但我无法获取它 如下文档所述 set name string value string expires numbe
  • Scala 宏:“无法从具有未解析类型参数的类型 T 创建 TypeTag”

    我正在玩 Scala 新宏并发现了这个gist from akshaal 看起来我不太明白 鉴于以下特征 fieldsMacro 或多或少与 akshaal 示例中的相同 case class Field I lt AnyRef name