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

标签 scala reflection macros scala-macros

在我的 Scala 代码中,我希望能够实例化一个新类。例如,假设我有以下代码:

class Foo { def foo=10 }
trait Bar { val bar=20 }

理想情况下,我希望能够执行以下操作:
def newInstance[A <: Foo] = { new A with Bar }
newInstance[Foo]

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

我想要做的是像下面的 Ruby 代码:
class SomeClass
  def create
    self.class.new
  end
end

class Other < SomeClass
end

Other.new.create # <- this returns a new Other instance

是否可以?

最佳答案

使用宏:

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")
  }
}

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

我用过 quasiquotes在这里是为了清楚起见,但您可以通过更多的工作手动构建树。不过,现在 quasiquotes 可以作为 Scala 2.10 的插件使用,这并没有什么好的理由。

关于scala - 使用 Scala 宏或反射实例化一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18838533/

相关文章:

java - Scala、Spring、WebFlow、Hibernate 和 Maven 或 Java、Spring、WebFlow、Hibernate 和 Maven

Jgit 的 Scala 版本

sbt : is there a way to run a single test without tags? 中的 ScalaTest

c# - 如何从对象中获取值但其类型无法访问

c++ - 匹配两个字符串的宏定义

scala - 在 Scala 中使用 Guava 范围

java - 使用 Java Reflections 获取通用类字段类型

c# - 在调用方方法中检索原始变量/参数名称(类似于 [CallerMemberName] 属性)

C++宏不替代?

rust 宏扩展忽略标记 `,` 和任何后续标记