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

Scala 使用宏重写val和var构造函数参数,scala,macros,Scala,Macros,我正在评估创建宏注释的可能性和努力,以扭转这一局面: @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 = _b

我正在评估创建宏注释的可能性和努力,以扭转这一局面:

@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
}
(或者使用
apply
方法创建一个
Foo
伴生对象,还不确定)

现在我从
ClassDef
主体中看到的是这样的东西

List(<paramaccessor> var bar: Int = _, 
  def <init>(bar: Int) = {
    super.<init>();
    ()
  })

正如Eugene所建议的,使用准晶石可以让这变得更容易。我还没有制定出一个完整的解决方案,但我尝试了一些方法,因此我认为按照这些方法会奏效:

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} }"
您可能会发现我的博客文章与此相关:

最相关的代码片段如下所示:

您可能还发现这对于定义getter和setter很有用:

我会使用准晶片。有了它们,您就不必担心类参数如何转换为ctor参数、支持字段等等的细节。
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} }"