You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Scala 3宏在编译时为@entity注解类生成私有无参构造方法

用Scala 3宏为@entity注解类生成私有无参构造方法

需求说明

我们需要实现一个自定义注解@entity,当类被该注解标注时,编译阶段自动生成一个私有的无参构造方法,这个构造方法会调用类的主构造方法,并为每个参数传入对应类型的默认值(如Long用0,String用null)。


1. 定义@entity注解

首先定义注解类,继承StaticAnnotation并指定宏处理入口:

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros

class entity extends StaticAnnotation {
  def macroTransform(using scala.quoted.Quotes): scala.quoted.Expr[Any] = EntityMacro.impl
}

2. 实现Scala 3宏注解处理器

通过Quoted API操作编译期语法树,生成无参构造方法并合并到原类:

import scala.quoted.*

object EntityMacro {
  def impl(using Quotes): Expr[Any] = {
    import quotes.reflect.*

    // 获取被注解的类定义
    val classDef = Position.ofMacroExpansion.owner.asClassDef
    val clsName = classDef.name

    // 获取主构造方法
    val primaryCtor = classDef.primaryConstructor.getOrElse(
      report.errorAndAbort(s"类 ${clsName} 必须包含主构造方法")
    )
    val ctorParams = primaryCtor.paramss.flatten

    // 生成参数默认值表达式
    val defaultArgs = ctorParams.map { param =>
      param.tpe.asType match {
        case '[Long] => Expr(0L)
        case '[String] => Expr(null: String)
        // 可扩展支持更多类型的默认值
        case t => report.errorAndAbort(s"暂不支持类型 ${t.show} 的默认值生成")
      }
    }

    // 生成私有无参构造方法语法树
    val noArgCtorDef = DefDef(
      name = "<init>",
      tparamss = Nil,
      paramss = Nil,
      returnTpt = TypeTree.of[Unit],
      rhs = Apply(Select(This(clsName), primaryCtor.name), defaultArgs.map(_.asTerm))
    ).withFlags(Flags.Private)

    // 将新构造方法添加到原类
    val newClassDef = classDef.copy(body = classDef.body :+ noArgCtorDef)

    // 转换为Expr返回
    Expr(newClassDef).asExprOf[Any]
  }
}

3. 使用示例

给目标类标注@entity,编译时自动生成私有无参构造方法:

@entity
class Student(val id: Long, val name: String)

编译后等价于:

class Student(val id: Long, val name: String) {
  private def this() = this(0L, null)
}

注意事项

  • 宏当前仅支持Long和String类型,如需扩展其他类型,在defaultArgs的匹配逻辑中添加对应分支即可。
  • 被注解类必须包含主构造方法,否则会触发编译错误。
  • 确保项目使用Scala 3.3+版本,原生支持宏特性,无需额外插件。

内容的提问来源于stack exchange,提问作者Golden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 12:50:22