我希望创建一个由宏生成的密封抽象和case类的层次结构。这里有一个类似的示例:http://docs.scala-lang.org/overviews/macros/typemacros.html,但现在已经过时了。 这仍然可行吗?
我认为,为某些指定的语法生成类型安全的AST将非常强大。最理想的情况是,IDE能够解析所有类。
我希望创建一个由宏生成的密封抽象和case类的层次结构。这里有一个类似的示例:http://docs.scala-lang.org/overviews/macros/typemacros.html,但现在已经过时了。 这仍然可行吗?
我认为,为某些指定的语法生成类型安全的AST将非常强大。最理想的情况是,IDE能够解析所有类。
首先是一些不要脸的自我推广:Eugene Burmako 和我将在明天的 Scalar 2014 上就类型提供者这个密切相关的话题发表讲话,如果你对这种东西感兴趣,我建议你看一下我们为演讲准备的示例项目。
虽然类型宏已经不再支持,但你可以使用宏注解从宏乐园(可作为Scala 2.10和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 的实现,例如。
宏注解非常实验性,其状态仍然未确定--例如,不能保证它们将随 Scala 2.12 一起发布。使用普通的 def
宏和结构类型也可以实现类似的功能(虽然不太干净)--请参阅上面链接的示例项目以获取更多详细信息和演示。无论如何,这种机制都受到许多人的关注,包括 Scala 宏系统的开发人员,因此即使宏注解最终消失了,也很可能有某种方法来实现您在此处描述的内容。
@expand trait Whatever
或@expand case class Whatever
将创建一个类型,但与准引用字符串中的代码无关。 - Jeff Schwabwget http://central.maven.org/maven2/org/scalamacros/paradise_2.11.6/2.1.0/paradise_2.11.6-2.1.0.jar
和scala -Xplugin:paradise_2.11.6-2.1.0.jar
。 - Mark Butler