Scala开发团队正在将实验版宏指令加入到即将发行的2.10版中。Scala宏指令提供了编译时元编程的高级形式。Scala宏网站描述道:

\u0026#xD;\n

\u0026#xD;\n

“宏指令显著简化了代码分析和代码生成,这使得它们成为处理大量现实用例的一种可选工具。传统上涉及编写和维护样板的场合可用宏以简单且易维护的方式实现。因此我们认为宏对于Scala编程语言是一项非常有价值的资产。”

\u0026#xD;\n

\u0026#xD;\n

Scala的宏指令允许开发者创建方法时以语法树转化的形式实现。这些是标准方法的定义,其在编译期间被显式地转换。举一个简单的例子,如assert方法:

\u0026#xD;\n

\u0026#xD;\nimport scala.reflect.makro.Context\u0026#xD;\nimport language.experimental.macros\u0026#xD;\nobject Asserts {\u0026#xD;\n   def assert(cond: Boolean, msg: Any) = macro Asserts.assertImpl\u0026#xD;\n   def raise(msg: Any) = throw new AssertionError(msg)\u0026#xD;\n   def assertImpl(c: Context)(cond: c.Expr[Boolean], msg: c.Expr[Any]): c.Expr[Unit] =\u0026#xD;\n         if(assertionsEnabled) c.reify(if(!cond.splice) raise(msg.splice))\u0026#xD;\n          else c.reify(())\u0026#xD;\n}\u0026#xD;\n

\u0026#xD;\n

assert宏就像代码中的一个普通的方法。该实现使用macro方法委托成为编译器扩展。该编译器扩展是方法assertImpl。assertImpl使用当前编译的上下文作为参数,而参数传给assert作为语法树(Expr)。这些语法树接下来被用作产生一个新的语法树并被插入至assert宏方法被调用的位置。

\u0026#xD;\n

对于assert宏来说,调用assert的方法assert(x != null, \"X is null\") 会给cond变量填充x != null的语法树而给msg变量填充\"X is null\"的语法树。对reify的调用会产生一个 if(x != null) Asserts.raise(\"X is null\")的或者()的新语法树。这个语法树会替代原始的assert(x != null, \"X is null\") 调用。

\u0026#xD;\n

reify和自清洁宏系统的更多细节可参考自清洁宏建议。

\u0026#xD;\n

有些人怀疑添加宏的效果,在一份题为《Scala Macros: \"Oh God Why?\"》博客中, Jay Kreps 评论道:

\u0026#xD;\n

\u0026#xD;\n

“这也是我对于Scala 宏指令的看法(Oh God Why?)。并不是因为宏指令或者这项提议有什么坏处,问题在于这真的是最重要的事情吗?”

\u0026#xD;\n

\u0026#xD;\n

Kreps接下来列举了一系列更重要的事情,包括编译速度、IDE支持、文档和编译文件大小。

\u0026#xD;\n

支持Kreps观点的大有人在。Ivan Todoroski在一封给Scala邮件列表的信中写到:

\u0026#xD;\n

\u0026#xD;\n

“在搜索问题的时候,Scala宏指令看起来只是一个低级别的、hacking风格的解决方案。它们在编写时太复杂,不太像Scala的风格,调试也麻烦,而且可能不过是为Scala的‘太多高深莫测的魔法’的形象增添了一笔。”

\u0026#xD;\n

\u0026#xD;\n

对此,Scala的发明者Martin Odersky回复说:

\u0026#xD;\n

\u0026#xD;\n

“宏的设计初衷和Scala语言的其他一般设计一样,都是为了使事情简单化。我们已经实现通过宏替换代码,希望其他功能也能这样实现。比如说,有一种强推在某种情况下消除 atomic { implicit transaction =\u0026gt; ... }中的隐含参数和许多其他相关情形。有了宏,这类问题就微不足道了。”

\u0026#xD;\n

\u0026#xD;\n

围绕着Scala宏的讨论已经逐渐偃旗息鼓,社区成员们正在等着看最终的实现。最终发布的版本始终没有放弃在宏指令方面的冒险。许多社区内基于宏的项目已经逐渐生根发芽,包括:

\u0026#xD;\n

Macrocosm——测试宏指令实际用例的库。

\u0026#xD;\n

Expecty——Groovy的Spock框架中的断言语句在Scala中的适应性改编。

\u0026#xD;\n

Slick——引进类似LINQ的数据库操作的尝试。Slick能转化Scala语法为数据库查询。

\u0026#xD;\n

ScalaMock——Scala的模拟对象测试库。

\u0026#xD;\n

在2.10.0-M4发布说明里可以找到其他一系列Scala2.10中的功能,包括:

\u0026#xD;\n

字符串插值

\u0026#xD;\n

Futures和Promises

\u0026#xD;\n

Value类

\u0026#xD;\n

动态类型

\u0026#xD;\n

隐式类

\u0026#xD;\n

Scala2.10版马上就要发布了,Scala开发团队号召人们试用最新的milestone发行版并提供反馈意见。你可以从这里下载最新版本。

\u0026#xD;\n


感谢杨赛对本文的审校。

\u0026#xD;\n

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

Scala语言将加入宏指令相关推荐

  1. 熟悉scala命令,scala语言运行超级素数和猴子大王

    实验目的 在Linux操作系统中安装Scala 输入"scala"命令,熟悉地运行Scala解释器 scala语言运行超级素数和猴子大王 实验仪器 Virtualbox管理器 实验 ...

  2. Bazel发布Beta版本,增加对Groovy、Rust和Scala语言的支持

    Bazel是Googe旗下的一款构建系统工具,六个月前Google将其开源,目前取得里程碑式的进展,发布了其第一个beta版本,增加了对数种语言和技术的支持. \\ Bazel是Google用来构建自 ...

  3. scala语言的底层是java实现的_Scala学习笔记一(与Java、Jvm的关系以及程序执行流程分析)...

    一.Scala语言与Java.Jvm的关系分析 Scala语言是马丁奥德斯基接触Java语言后,针对Java语言的特点,将函数式编程语言的特点融合到Java中,由此发明的.Scala语言和Java语言 ...

  4. android studio scala插件,Scala 语言开发Andorid ,开发环境的搭建(一)

    Scala 语言开发Andorid ,开发环境的搭建 厌倦 Java 繁琐的语法,为了更优雅的开发 Android 程序,Scala 代替 Java 是一个不错的尝试. 开发前可以学习 Scala 的 ...

  5. Apache Spark学习:利用Scala语言开发Spark应用程序

    Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可以阅读网络教程 A Scala Tutorial for Ja ...

  6. Scala 语言输出的三种方式

    Scala 语言输出的三种方式 字符串通过+号连接(类似 java). printf 用法 (类似 C 语言)字符串通过 % 传值. 字符串通过$引用(类似 PHP).

  7. Scala 语言转义字符

    Scala 语言转义字符

  8. Scala语言整理(一)

    与Java对比 语法对比 对比项 Java Scala 说明 标识符 / / 反引号括起来的字符也是标识符. 语句结束 分号(;) 分号(;)或者换行   包 package ... package ...

  9. scala语言示例_var关键字与Scala中的示例

    scala语言示例 Scala var关键字 (Scala var keyword) The var Keyword in scala is used to declare variables. As ...

最新文章

  1. 字段变成小写 序列化_序列化/反序列化
  2. matlab 小技巧
  3. GSON反序列化时,字符串被转换成科学记数法的问题处理
  4. CNN基本步骤以及经典卷积(LeNet、AlexNet、VGGNet、InceptionNet 和 ResNet)网络讲解以及tensorflow代码实现
  5. matlab中solve和resolve,resolve和solve的区别
  6. Leetcode--91. 解码方法
  7. win7虚拟机手机版_UTM 2.0 虚拟机来了,解决上网和无声音问题
  8. linux修改密码的几种方法
  9. 7.4读写锁(ReadWriteLock)
  10. GNOME Screencaster 将支持 Miracast P2P 传输
  11. 什么是单工,半双工,全双工
  12. Android——AndroidX
  13. win10 风格的 OA 管理系统 skyeye 更新,新增项目模块
  14. HTML5第三弹:亦酷亦萌的网络拓扑图
  15. YAGNI(You “Ain‘t Gonna Need It)---您“不需要”
  16. ubuntu 修复grub
  17. overflow第一次觉得你有点可恶
  18. javaMail发送邮件实例
  19. 考研全真模拟试题卷及往年真题卷附答案
  20. 1319:星号阵列1

热门文章

  1. MessageBox、::MessageBox 、AfxMessageBox三者的区别
  2. linux之LAMP架构搭建
  3. JavaScript中的document.cookie的使用
  4. Gigabit Ethernet复制数据会异常的缓慢
  5. linux手动同步文件命令,Linux文件同步命令rsync详解
  6. java docx转html实例_Java实现将word转换为html的方法示例【doc与docx格式】
  7. linux安装手动划分目录,Linux目录配置整理
  8. oracle通过执行计划cost,Oracle 执行计划(5)—cost成本之索引范围扫描-B树索引
  9. 联发科mtk和骁龙730哪个好_不惧高通挑战!联发科G90芯片发布,强势干翻骁龙730...
  10. linux音量模块,Linux下的音量控制器alsamixer