gpt4 book ai didi

scala - 使用宏重写 val 和 var 构造函数参数

转载 作者:行者123 更新时间:2023-12-01 03:53:32 24 4
gpt4 key购买 nike

我正在评估创建宏注释以解决此问题的可能性和努力:

@txn class Foo(var bar: Int)

进入这个:
import concurrent.stm.{Ref, InTxn}

class Foo(bar0: Int) {
private val _bar = Ref(bar0)

def bar(implicit tx: InTxn): Int = _bar()
def bar_=(value: Int)(implicit tx: InTxn): Unit = _bar() = value
}

(或者可能使用 Foo 方法创建一个 apply 伴随对象,还不确定)

现在我从 ClassDef 看到的 body 是这样的
List(<paramaccessor> var bar: Int = _, 
def <init>(bar: Int) = {
super.<init>();
()
})

所以 bar显示为没有 init ( _ ) 的参数访问器,也作为 <init> 的参数方法。

我将如何重写那个 body ?
import scala.reflect.macros.Context
import scala.language.experimental.macros
import scala.annotation.StaticAnnotation

class txn extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro txnMacro.impl
}
object txnMacro {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
val inputs = annottees.map(_.tree).toList

def reportInvalidAnnotationTarget(): Unit =
c.error(c.enclosingPosition,
"This annotation can only be used on a class definition")

val expandees: List[Tree] = inputs match {
case cd @ ClassDef(mods, nme, tp, tmp @ Template(parents, self, body)) :: Nil =>
println(s"Body: $body")
???

case _ =>
reportInvalidAnnotationTarget()
inputs
}

val outputs = expandees
c.Expr[Any](Block(outputs, Literal(Constant(()))))
}
}

最佳答案

正如 Eugene 所建议的,使用 quasiquotes 可以使这更容易。我还没有整理出完整的解决方案,但我尝试了一些部分,所以我认为这些方法会起作用:

case q"class $name extends $parent with ..$traits { ..$body }"=>
val newBody = body.flatMap {
case q"var $varName = $varBody" =>
List(
//put the three defs you need here. some variant of this ...
q"""private val ${stringToTermName("_" + varName.toString)} = Ref(${stringToTermName(varName.name + "0")})""",
//etc ...
)
case other => other
}
q"class $name extends $parent with ..$ttraits { ..${(newBody).toList} }"

您可能会发现我的博文相关: http://imranrashid.com/posts/learning-scala-macros/

最相关的代码片段在这里:
https://github.com/squito/learn_macros/blob/master/macros/src/main/scala/com/imranrashid/oleander/macros/FillTraitDefs.scala#L78

您可能还会发现这对于定义 getter 和 setter 很有用:
https://groups.google.com/forum/#!searchin/scala-user/macro|sort:date/scala-user/Ug75FW73mJI/F1ijU0uxZAUJ

关于scala - 使用宏重写 val 和 var 构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19662976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com