使用Scala Macro或反射实例化一个类 [英] Instantiate a class with Scala Macro or reflection

查看:232
本文介绍了使用Scala Macro或反射实例化一个类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

On my scala code, I want to be able to instantiate a new class. For instance, supose I have the code below:

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

理想情况下,我希望能够执行以下操作:

Ideally, I want to be able to do something like:

def newInstance[A <: Foo] = { new A with Bar }
newInstance[Foo]

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

But, of course this doesn't work. I tried to use reflection to instantiate a class, but it seems that I'm only able to instantiate a new class (and not mix-in with a trait). I think it would be possible to make this work using Macros, but I'm not sure even where to start.

我想要做的就像下面的Ruby代码一样:

What I'm trying to do is like the following Ruby code:

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

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

This will work as expected, and will fail at compile time if you try to instantiate a class that doesn't have a no-argument constructor.

为了清楚起见,我在这里使用准报价,但是您可以通过手动工作来构建树.不过,现在并没有充分的理由,因为准报价可以作为Scala 2.10的插件使用.

I've used quasiquotes here for the sake of clarity, but you could build the tree manually with a little more work. There's not really any good reason to, though, now that quasiquotes are available as a plugin for Scala 2.10.

这篇关于使用Scala Macro或反射实例化一个类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆