如果您使用的是 Scala 2.10 或更高版本,则可以使用以下内容在 repl 中显示脱糖的 scala 代码:
import scala.reflect.macros.Context // use BlackboxContext if you're in 2.11
import scala.reflect.runtime.universe._
import scala.language.experimental.macros
def _desugar(c : Context)(expr : c.Expr[Any]): c.Expr[Unit] = {
import c.universe._
println(show(expr.tree))
reify {}
}
def desugar(expr : Any): Unit = macro _desugar
这将允许您传入代码块,并查看它们转换成的内容。对于您的示例,在 repl 中:
scala> class A {
| def getInt: Int = throw new RuntimeException
| def map(f: Int => Boolean): Boolean = f(getInt)
| def flatMap(f: Int => Boolean): Boolean = f(getInt)
| }
defined class A
scala> desugar {
| for {
| x <- new A
| y <- new A
| } yield x == y
| }
new $line15.$read.$iw.$iw.$iw.$iw.A().flatMap(((x: Int) => new $line15.$read.$iw.$iw.$iw.$iw.A().map(((y: Int) => x.==(y)))))
有点乱,因为 repl 创建了几个中间临时变量,但是你可以看到正在发生的事情的结构。
new A().flatMap { (x: Int) =>
new A().map { (y: Int) =>
x == y
}
}
这适用于大多数任何表达式,并允许您检查实际代码在编译期间将转换为什么。
更新
我应该指出我的来源——我的版本是在 github 上的Macrocosm 存储desugar
库中找到的函数的略微修改版本。