问题描述
我想创建一个宏生成的密封抽象类和案例类的层次结构.http://docs.scala-lang.org 有一个类似的例子/overviews/macros/typemacros.html 但现在已过时.这还有可能吗?
I would like to create a macro generated hierarchy of sealed abstract and case classes. There was an example similar to this with http://docs.scala-lang.org/overviews/macros/typemacros.html but is is now obsolete. Is this still possible?
我认为为某些指定的语法生成类型安全的 AST 会非常强大.理想情况下,IDE 能够解析所有类.
I think it would be incredibly powerful to generate a type safe AST for some specified grammar. Ideally with an IDE able to resolve all the classes.
推荐答案
首先是一些无耻的自我推销:Eugene Burmako 和我是类型提供者,一个密切相关的话题,在Scalar 2014 明天,我鼓励你看看 示例项目 如果您对此类事情感兴趣,我们会为您的演讲汇总.
First for some shameless self-promotion: Eugene Burmako and I are giving a talk on type providers, a closely related topic, at Scalar 2014 tomorrow, and I encourage you to take a look at the example project we put together for the talk if you're interested in this kind of thing.
虽然不再支持类型宏,但您可以使用宏注释 来自 宏观天堂(可作为 Scala 2.10 和 2.11 的插件使用):>
While type macros are no longer supported, you can accomplish essentially the same thing with macro annotations from macro paradise (which is available as a plugin for Scala 2.10 and 2.11):
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.Context
// Add constructor arguments here.
class expand extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro Expander.expand_impl
}
object Expander {
def expand_impl(c: Context)(annottees: c.Expr[Any]*) = {
import c.universe._
annottees.map(_.tree) match {
case List(q"trait $name") => c.Expr[Any](
// Add your own logic here, possibly using arguments on the annotation.
q"""
sealed trait $name
case class Foo(i: Int) extends $name
case class Bar(s: String) extends $name
case object Baz extends $name
"""
)
// Add validation and error handling here.
}
}
}
然后:
scala> @expand trait MyADT
defined trait MyADT
defined class Foo
defined class Bar
defined module Baz
例如,您可以向将在编译时可用的注释添加参数,从而允许您解析可用于生成 ADT 实现的外部资源.
You can add arguments to the annotation that will be available at compile time, allowing you to parse an external resource that you can use to generate the implementation of the ADT, for example.
宏注释是非常实验性的,它们的状态仍然悬而未决——例如,不能保证它们会随 Scala 2.12 一起提供.使用普通的旧 def
宏和结构类型可以实现类似的(虽然不是很干净)——参见 上面链接的示例项目以获得更多详细信息和一些演示.无论如何,这种机制对很多人都很感兴趣,包括 Scala 宏系统的开发人员,因此即使宏注释在未来的某个时刻消失了,也可能有某种方法来完成您在此处描述的内容.
Macro annotations are very experimental and their status is still up in the air—there's no guarantee that they'll ship with Scala 2.12, for example. Something similar (although not quite so clean) is possible using plain old def
macros and structural types—see the example project linked above for more detail and some demonstrations. In any case, this kind of mechanism is of interest to many people, including the developers of Scala's macro system, so even if macro annotations disappear at some point down the road, there's likely to be some way to accomplish what you've described here.
这篇关于“动态地"使用宏创建案例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!