前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Scala Macro 现状介绍

Scala Macro 现状介绍

作者头像
joymufeng
发布2018-05-17 15:52:31
1.5K0
发布2018-05-17 15:52:31
举报

1. Scala Macro

Scala Macro 是 Scala 2.10 版本增加的一个新的语言特性,让开发者可以在编译期动态修改/生成代码,为开发工作提供了很大的灵活性。Scala Macro 发展的高峰是 Scala 2.11 版本,增加更多新特性,其中最耀眼的便是QUASIQUOTES,它可以帮助开发者屏蔽编译器底层的细节,很大程度上简化了Macro的编写工作。到了Scala 2.12,Scala Macro 基本上没有太多变化,并且直到目前为止,Scala Macro 一直被打着EXPERIMENTAL标签,冥冥之中似乎预示着不好的征兆,果然 Scala Macro 最终还是被官方抛弃了,取而代之的是在 Dotty 中重新实现了,并且将会在2020年的 Scala 3.0 中发布。其实早在2018年的3月17日,Scala Macro 的核心作者 Eugene Burmako 就已经宣布放弃 Scala Macro 了,似乎也是在为 Scala 3.0 做准备。

2. Scala Meta

在 Scala Macro 发展过程中衍生了另外一个项目 Scala Meta , 本来雄心壮志要取代现有的 Scala Macro,可是走着走着却跑偏了,现在的目标是面向开发工具提供服务,典型的衍生项目是 Scalafmt,可以为开发者提供代码格式化服务。

3. 当前如何使用 Scala Macro ?

从 Scala 2.11 开始,Scala Macro 已经被合并至 Scala Reflect ,所以只要在项目中添加 Scala Reflect 依赖便可以进行Macro开发了:

libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.12.4"

有意思的是运行时Reflect和Macro共享底层的基础API,这意味着二者可以通过底层的API进行交互。在开发Macro时,可以使用 Runtime Reflect ,例如:

import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
import scala.reflect.runtime.{ universe => ru }

object Macros {
  def allClasses: List[String] = macro allClassesImpl
  def allClassesImpl(c: Context) = {
    import c.universe._

    val clsList =
      ru
        .runtimeMirror(this.getClass.getClassLoader)
        .staticPackage("models").typeSignature.decls
        .filter(s => s.isClass && s.asClass.isCaseClass)
        .map{ s =>
          s.asClass.typeSignature
          s.fullName
        }.toList

    q"$clsList"
  }
}

在Macro方法实现中,可以通过 runtime universe 读取 models package 下的类列表。这只是一个示例用于说明 Scala Reflect 的run time和compile time可以很好的一起协作,但是由于JVM 类加载机制,上面的代码其实无法工作,每次运行读取的类列表都可能不同。另外,在进行Macro开发时,要注意配合构建工具的增量编译以及热加载。

更详细内容请参考:官方开发文档

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档