为了账号安全,请及时绑定邮箱和手机立即绑定

获得Scala的/理解表达的贬义部分?

获得Scala的/理解表达的贬义部分?

海绵宝宝撒 2019-12-26 08:50:54
有人知道在for / comprehension表达式实际尝试在REPL(或编译器)中进行编译之前,该如何获得for / comprehension表达式的(仅限于Scala部分)经过简化的翻译?到目前为止,我唯一发现的是编译器的“ -print”标志,但这为您提供了完整的Scala翻译…
查看完整描述

3 回答

?
蓝山帝景

TA贡献1843条经验 获得超7个赞

正如我在另一个主题中已经说过的那样,scalac -print打印出scala代码,而不是java。它将所有与Java不直接兼容的scala关键字转换为普通的scala代码。让编译器仅翻译部分afaik是不可能的。但基本上,理解力总是以相同的方式翻译。


这样的简单/收益


for(x <- List(1,2,3)) yield x*x

将被翻译成


List(1,2,3).map {x => x*x}

而且没有产量


for(x <- List(1,2,3)) println(x)


List(1,2,3).foreach{x => println(x)}

嵌套的fors将转换为嵌套的flatMap / map构造


for(x <- List(1,2,3); y <- List(4,5,6)) yield x*y

将被翻译成


List(1,2,3).flatMap { x =>

  List(4,5,6).map { y =>

    x*y

  }

}

所以绝对没有魔术


查看完整回答
反对 回复 2019-12-26
?
慕神8447489

TA贡献1780条经验 获得超1个赞

在REPL中似乎不存在直接对“ for / comprehension”表达式进行解糖的任何可能性。但是作为一种替代方案,可以使用一些Scala编译器选项,例如“ -print”或简单表达式“ Xprint:typer -e”


例:


要从文件获取desugard输出,请使用“ -print”标志:


# scala -print file.scala

要对一个简单的单线表达式进行解糖,请使用“ -Xprint:typer -e”标志:


# scala -Xprint:typer -e "for (i <- 0 to 100) yield i"


查看完整回答
反对 回复 2019-12-26
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

宏呢?


import scala.reflect.macros.Context

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) = macro _desugar

可以根据您的要求直接在REPL中使用:


scala> desugar { for(i <- List(1,2,3,4,5)) yield i }

immutable.this.List.apply[Int](1, 2, 3, 4, 5).map[Int, Any](((i: Int) =>

i))(immutable.this.List.canBuildFrom[Int])


scala> desguar { for(i <- (0 to 10) if (i > 5)) yield i }

scala.this.Predef.intWrapper(0).to(10).withFilter(((i: Int) => i.>(5))).map[Int,

Any](((i: Int) => i))(immutable.this.IndexedSeq.canBuildFrom[Int])

它也适用于其他任意表达式。


scala> desugar {

     |   val x = 20

     |   val y = 10

     |   println(x + y)

     | }

{

  val x: Int = 20;

  val y: Int = 10;

  scala.this.Predef.println(x.+(y))

}

这可能是您最接近所要查询的内容,而不必随时将数据编译或转储到文件中。您可以直接在REPL中定义宏,也可以在通过:load命令加载的外部文件中定义宏。

查看完整回答
反对 回复 2019-12-26
  • 3 回答
  • 0 关注
  • 402 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信