sjson 中奇怪的 scala 片段(宏?)

Weird scala snippet in sjson (macro?)

我在查看sjson的源代码时发现了这段奇怪的代码:

<#list 2..22 as i> 
<#assign typeParams><#list 1..i as j>T${j}<#if i !=j>,</#if></#list></#assign>

  def asProduct${i}[S, ${typeParams}](<#list 1..i as j>f${j}: String<#if i != j>,</#if></#list>)(apply : (${typeParams}) => S)(unapply : S => Product${i}[${typeParams}])(implicit <#list 1..i as j>bin${j}: Format[T${j}]<#if i != j>,</#if></#list>) = new Format[S]{
    def writes(s: S) = {
      val product = unapply(s)
      JsObject(
        List(
          <#list 1..i as j>
          (tojson(f${j}).asInstanceOf[JsString], tojson(product._${j}))<#if i != j>,</#if>
          </#list>
        ))
    }
    def reads(js: JsValue) = js match {
      case JsObject(m) => // m is the Map
        apply(
          <#list 1..i as j>
          fromjson[T${j}](m(JsString(f${j})))<#if i != j>,</#if>
          </#list>
        )
      case _ => throw new RuntimeException("object expected")
    }
  }  
  </#list>

乍一看,它看起来像一个宏,但我不确定,因为我看到的是不同的,它们使用 类 修改 Scala AST,如 WeakTypeTag 等等。我知道此方法正在生成具有 20 个不同参数列表的 asProduct 方法。但是,当我在我的 REPL 中复制这段代码时,它没有被正确解析,我得到以下错误:

<console>:1: error: identifier expected but double literal found.

还有一堆错误。

我想知道:

如评论所述,sjson 使用 FMPP 模板生成 scala 文件。您可以在项目构建中找到它是如何完成的:

https://github.com/debasishg/sjson/blob/master/project/SJsonProject.scala#L61-L86

因此它与 scala 宏功能无关。

根据我的经验,大多数项目都需要这种代码生成,为此使用一些库或 SBT 插件。

FMPP 方法的替代方法是使用 SBT 插件。我个人更喜欢 sbt-boilerplate 插件。它易于使用,并且在模板中需要的代码更少。但它仍然是基于模板的代码生成方法。