使用Scala宏或反射实例化一个类

Mau*_*abo 7 reflection macros scala scala-macros

在我的scala代码中,我希望能够实例化一个新类.例如,我有以下代码:

class Foo { def foo=10 }
trait Bar { val bar=20 }
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望能够做到这样的事情:

def newInstance[A <: Foo] = { new A with Bar }
newInstance[Foo]
Run Code Online (Sandbox Code Playgroud)

但是,当然这不起作用.我试图使用反射来实例化一个类,但似乎我只能实例化一个新类(而不是与特征混合).我认为可以使用宏来完成这项工作,但我不确定从哪里开始.

我想要做的是像下面的Ruby代码:

class SomeClass
  def create
    self.class.new
  end
end

class Other < SomeClass
end

Other.new.create # <- this returns a new Other instance
Run Code Online (Sandbox Code Playgroud)

可能吗?

Tra*_*own 11

用宏:

import scala.language.experimental.macros
import scala.reflect.macros.Context

object MacroExample {
  def newInstance[A <: Foo]: A with Bar = macro newInstance_impl[A]

  def newInstance_impl[A <: Foo](c: Context)(implicit A: c.WeakTypeTag[A]) = {
    import c.universe._

    c.Expr[A with Bar](q"new $A with Bar")
  }
}
Run Code Online (Sandbox Code Playgroud)

这将按预期工作,如果您尝试实例化一个没有无参数构造函数的类,它将在编译时失败.

为了清楚起见,我在这里使用了quasiquotes,但你可以用更多的工作手动构建树.但是,现在没有任何合理的理由可以作为Scala 2.10的插件使用quasiquotes.