如何使用宏注释向 Scala 案例类添加无参数构造函数?

2024-01-09

我正在尝试回答这个问题 https://stackoverflow.com/questions/13812172/how-can-i-create-an-instance-of-a-case-class-with-constructor-arguments-with-no.

而不是写:

case class Person(name: String, age: Int) {
  def this() = this("",1)
}

我想我应该使用宏注释来扩展它:

@Annotation
case class Person(name: String, age: Int)

所以我尝试将新的构造函数添加为普通的旧构造函数DefDef在宏注释的 impl 中使用准引号,例如:

val newCtor = q"""def this() = this("", 1)"""
val newBody = body :+ newCtor
q"$mods class $name[..$tparams](..$first)(...$rest) extends ..$parents { $self => ..$newBody }"

但这会返回一个错误:called constructor's definition must precede calling constructor's definition

有办法解决这个问题吗?我错过了什么?

谢谢参观, ——朱利安


事实证明,在宏注释中生成辅助构造函数的非常自然的意图暴露了两个不同的问题。

1)第一期(https://issues.scala-lang.org/browse/SI-8451 https://issues.scala-lang.org/browse/SI-8451) 是关于准引号为辅助构造函数发出错误的树形状。该问题已在 2.11.0-RC4(尚未发布,目前以 2.11.0-SNAPSHOT 形式提供)和 2.10.x 的天堂 2.0.0-M6(昨天发布)中得到修复。

2)第二个问题是关于未分配的位置在类型检查期间造成严重破坏。奇怪的是,当对构造函数的调用进行类型检查时,打字机使用位置来确定这些调用是否合法。这不是那么容易修补的,我们必须解决以下问题:

         val newCtor = q"""def this() = this(List(Some("")))"""
-        val newBody = body :+ newCtor
+
+        // It looks like typer sometimes uses positions to decide whether stuff
+        // (secondary constructors in this case) typechecks or not (?!!):
+        // https://github.com/xeno-by/scala/blob/c74e1325ff1514b1042c959b0b268b3c6bf8d349/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L2932
+        //
+        // In general, positions are important in getting error messages and debug
+        // information right, but maintaining positions is too hard, so macro writers typically don't care.
+        //
+        // This has never been a problem up until now, but here we're forced to work around
+        // by manually setting an artificial position for the secondary constructor to be greater
+        // than the position that the default constructor is going to get after macro expansion.
+        //
+        // We have a few ideas how to fix positions in a principled way in Palladium,
+        // but we'll have to see how it goes.
+        val defaultCtorPos = c.enclosingPosition
+        val newCtorPos = defaultCtorPos.withEnd(defaultCtorPos.endOrPoint + 1).withStart(defaultCtorPos.startOrPoint + 1).withPoint(defaultCtorPos.    point + 1)
+        val newBody = body :+ atPos(newCtorPos)(newCtor)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用宏注释向 Scala 案例类添加无参数构造函数? 的相关文章

随机推荐

  • DataTables 服务器端分页

    我有工作 Spring REST 应用程序与客户端分页 默认由 DataTables 和一切正常 现在我需要将其更改为服务器端分页 我遇到了问题 因为不知道如何从数据表中获取客户端想要查看的页码信息 我在 DT 手册中找不到任何有用的内容
  • 对数组进行排序以避免相邻项具有重复属性

    我有一系列对象 每个对象都有一个颜色属性 可以是 红色 蓝色 黄色 绿色 橙色 或 紫色 数组中有 20 30 个对象 因此颜色重复 我的目标是对数组进行排序 以便没有颜色彼此相邻 颜色的分布并不完全均匀 但很接近 这是我到目前为止所拥有的
  • vim 过滤器和 stdout/stderr

    当我使用 通过过滤器运行文件的内容 过滤器失败 它返回除 0 之外的另一个代码 并向 stderr 打印一条错误消息 我的文件被此错误消息替换 如果过滤器返回指示错误和 或忽略过滤器程序写入 stderr 的输出的状态代码 是否有办法告诉
  • 使用 VSTO 对 Excel 插件进行单元测试

    我一直在尝试测试我的插件但没有成功 即使在查看了各种来源之后MSDN https blogs msdn microsoft com varsha 2010 08 17 writing automated test cases for vst
  • WCF 方法被调用两次

    我有一个将数据返回到桌面应用程序的网络服务 我遇到的问题是 当网络服务返回少量数据时 一切正常 但当数据量很大时 它会抛出以下异常 System Net WebException 基础连接已关闭 接收时发生意外错误 当我调试 Web 服务时
  • 以编程方式检查 DLL/EXE 文件是否使用authenticode 签名的最佳方法是什么?

    我不想验证证书 我想在构建服务器上使用它来检查所有文件并列出我们可能忘记签名的文件 怎么样使用Get AuthenticodeSignature http technet microsoft com en us library dd3476
  • 我想在 SQL 中使用递归返回新列?

    我有一个表格 其列如下所示 Employee ID Manager ID E068 E067 E071 E067 E229 E069 E248 E144 E226 E223 E236 E241 E066 E001 E067 E001 E14
  • 在控制台应用程序中人为填充 HttpContext 对象

    我正在为 log4net 编写一个包装器库 该库应该能够捕获上下文信息 例如查询字符串 cookie 表单字段等 我从控制台应用程序调用这个包装类 而不是 TDD 类 有没有办法在控制台应用程序中填充 HttpContext 对象 如下所示
  • 如何安装 clang 头文件?

    我在 MacOS 上安装了 clang 在 usr bin clang 中 我认为 Mac 上默认安装了 clang 但是 当我尝试在脚本中包含 clang 头文件时 它说找不到它们 Example cpp 1 10 fatal error
  • 如何开发具有交错列和自调整大小单元格的自定义 UICollectionViewLayout?

    我正在开发一个已经在 Android 上开发的应用程序的 iOS 版本 该应用程序具有以下 2 列自调整大小 宽度固定但高度可变 单元格的网格 在 Android 版本中实现这一点很容易 因为 Google 提供了StaggeredGrid
  • 共享库如何在混合 64 位/32 位系统中工作?

    早上好 在 64 位 RedHat 机器上 我们必须编译并运行 32 位应用程序 同时 我设法编译了所需的 gcc 版本 4 0 3 和 32 位所需的所有运行时库 并将 LD LIBRARY PATH 设置为指向 32 位版本 但现在在剩
  • 评估 VS Code 扩展中的环境变量

    我正在 VS Code 中开发一个扩展 以添加对 OpenSCAD 基于脚本的 3D 建模程序 的语言支持 目前 我一直在研究一种从 VS Code 在 OpenSCAD 中打开 预览文件的方法 我已经能够使用自己的预览管理器成功完成此操作
  • 汇编 NASM 中的随机数生成

    我正在从事汇编 nasm 的大学项目 唯一的问题是我无法生成 162 到 278 之间的偶数随机数 我尝试了很多算法 但似乎无法限制范围内的数字 是否有一个小技巧或调整来获得范围内所需的数字 目的是在屏幕上随机显示一个水果 主要是贪吃蛇游戏
  • React中的apexchart方法

    我正在使用 apexcharts 并做出反应 我需要隐藏一系列 但我不知道如何在我的代码中实现这些方法 这个想法是使用 data4 进行一些计算并将其显示在自定义工具提示上 如何隐藏图表中的数据4但仍在后台使用数据 我的代码是这样的 imp
  • 一根衬垫可压平嵌套对象

    我需要展平嵌套对象 需要一个内衬 不确定此过程的正确术语是什么 我可以使用纯Javascript或库 我特别喜欢下划线 我有 a 2 b c 3 而且我要 a 2 c 3 我试过了 var obj fred 2 jill 4 obby jo
  • 如何让 SCons 替换已安装文本文件中的文本

    我希望能够在从 scons 安装一些 python 脚本时替换模板变量 SOFTWARE VERSION scons已经有这样的功能了吗 如果没有 那么挂钩 scons 安装过程的最佳方法是什么 以便我可以在安装过程中执行此操作 你可以使用
  • Eclipse Spring Boot - 在 TransactionAutoConfiguration 和 Neo4jDataAutoConfiguration 之间检测到自动配置周期

    从昨天开始 我在正在开发的 Spring Boot 应用程序 1 5 2 RELEASE 上遇到了一个非常奇怪的错误 在 Eclipse 中运行项目时 我开始遇到以下异常 从命令行运行它时 一切正常 但在开发和调试时我仍然需要从 Eclip
  • 如何构建包含 Mac Catalyst 的 Fat Framework?

    如何构建一个包含构建 Mac Catalyst 应用程序所需架构的胖框架 苹果引入了一个 未记录的 新目标 x86 64 apple ios13 0 macabi 如何构建此目标取决于您的框架构建环境 1 XC框架 如果您的框架是 Xcod
  • 如何创建asyncTask来防止networkOnMainThreadException

    我是 Android 应用程序开发新手 我尝试开发一个android服务器客户端聊天 对于我的第一个项目 这是客户端的代码 当客户按下btnJoin 它将连接到服务器并发送一个字符串 我读过很多例子 其中很多 看起来像这样 我有一个netw
  • 如何使用宏注释向 Scala 案例类添加无参数构造函数?

    我正在尝试回答这个问题 https stackoverflow com questions 13812172 how can i create an instance of a case class with constructor arg