scala中的问题理解脱糖?
Problem in scala for-comprehension de-sugar?
我有以下理解,我使用命令 scala -Xprint:parser ForComprehensionDemo.scala
去除了糖分。当我复制脱糖方法并调用它时,它产生的结果与 for-comprehension 不同。知道为什么吗?
求理解:
object ForComprehensionDemo {
def main(args: Array[String]): Unit = {
forWithIf(true)
}
def forWithIf(condition: Boolean) = {
val x = for {
a <- name(0)
b <- if (condition) {
name(1)
name(2)
} else {
name(100)
}
c <- name(2)
} yield {
a + b + c
}
println(x)
}
def name(x: Int): Option[String] = {
println("called for :" + x)
x match {
case 0 => Some(" aa ")
case 1 => Some(" bb ")
case 2 => Some(" cc ")
case _ => Some(" not identified ")
}
}
}
产生结果:
called for :0
called for :1
called for :2
called for :2
Some( aa cc cc )
脱糖码
def forWithIf(condition: Boolean) = {
val x = name(0).flatMap(((a) => if (condition)
{
name(1);
name(2)
}
else
name(100).flatMap(((b) => name(2).map(((c) => a.$plus(b).$plus(c)))))));
println(x)
};
产生结果:
called for :0
called for :1
called for :2
Some( cc )
只是漂亮打印机中的一个错误。它缺少 if-else 周围的括号。
总的来说,scala 2 不能非常忠实地代表 parens,但 scala 3 更好。
package desugar {
object ForComprehensionDemo extends scala.AnyRef {
def main(args: Array[String]): Unit = forWithIf(true);
def forWithIf(condition: Boolean) = {
val x = name(0).flatMap(((a) => (if (condition)
{
name(1);
name(2)
}
else
name(100)).flatMap(((b) => name(2).map(((c) => a.$plus(b).$plus(c)))))));
println(x)
};
def name(x: Int): Option[String] = {
println("called for :".$plus(x));
x match {
case 0 => Some(" aa ")
case 1 => Some(" bb ")
case 2 => Some(" cc ")
case _ => Some(" not identified ")
}
}
}
}
我很好奇 Scala 3 说了什么。 -Xprint:all
在打字员之后说:
sugar.ForComprehensionDemo.name(0).flatMap[String](
{
def $anonfun(a: String): Option[String] =
(if condition then
{
sugar.ForComprehensionDemo.name(1)
sugar.ForComprehensionDemo.name(2)
}
else
{
sugar.ForComprehensionDemo.name(100)
}
).flatMap[String](
{
def $anonfun(b: String): Option[String] =
sugar.ForComprehensionDemo.name(2).map[String](
{
def $anonfun(c: String): String =
{
a.+(b).+(c)
}
closure($anonfun)
}
)
closure($anonfun)
}
)
closure($anonfun)
}
)
闭包更难理解,但它有括号。在解析器之后打印没有用。
只是为了比较这里是 IntelliJ Desugar Scala code...
输出(手动缩写 FQN)
def forWithIf(condition: Boolean) = {
val x = name(0)
.flatMap(((a) =>
(if (condition) {
name(1);
name(2)
} else {
name(100)
})
.flatMap(((b) =>
name(2)
.map(((c) => a.$plus(b).$plus(c)))))
));
println(x)
};
确认 som-snytt 的回答。
我有以下理解,我使用命令 scala -Xprint:parser ForComprehensionDemo.scala
去除了糖分。当我复制脱糖方法并调用它时,它产生的结果与 for-comprehension 不同。知道为什么吗?
求理解:
object ForComprehensionDemo {
def main(args: Array[String]): Unit = {
forWithIf(true)
}
def forWithIf(condition: Boolean) = {
val x = for {
a <- name(0)
b <- if (condition) {
name(1)
name(2)
} else {
name(100)
}
c <- name(2)
} yield {
a + b + c
}
println(x)
}
def name(x: Int): Option[String] = {
println("called for :" + x)
x match {
case 0 => Some(" aa ")
case 1 => Some(" bb ")
case 2 => Some(" cc ")
case _ => Some(" not identified ")
}
}
}
产生结果:
called for :0
called for :1
called for :2
called for :2
Some( aa cc cc )
脱糖码
def forWithIf(condition: Boolean) = {
val x = name(0).flatMap(((a) => if (condition)
{
name(1);
name(2)
}
else
name(100).flatMap(((b) => name(2).map(((c) => a.$plus(b).$plus(c)))))));
println(x)
};
产生结果:
called for :0
called for :1
called for :2
Some( cc )
只是漂亮打印机中的一个错误。它缺少 if-else 周围的括号。
总的来说,scala 2 不能非常忠实地代表 parens,但 scala 3 更好。
package desugar {
object ForComprehensionDemo extends scala.AnyRef {
def main(args: Array[String]): Unit = forWithIf(true);
def forWithIf(condition: Boolean) = {
val x = name(0).flatMap(((a) => (if (condition)
{
name(1);
name(2)
}
else
name(100)).flatMap(((b) => name(2).map(((c) => a.$plus(b).$plus(c)))))));
println(x)
};
def name(x: Int): Option[String] = {
println("called for :".$plus(x));
x match {
case 0 => Some(" aa ")
case 1 => Some(" bb ")
case 2 => Some(" cc ")
case _ => Some(" not identified ")
}
}
}
}
我很好奇 Scala 3 说了什么。 -Xprint:all
在打字员之后说:
sugar.ForComprehensionDemo.name(0).flatMap[String](
{
def $anonfun(a: String): Option[String] =
(if condition then
{
sugar.ForComprehensionDemo.name(1)
sugar.ForComprehensionDemo.name(2)
}
else
{
sugar.ForComprehensionDemo.name(100)
}
).flatMap[String](
{
def $anonfun(b: String): Option[String] =
sugar.ForComprehensionDemo.name(2).map[String](
{
def $anonfun(c: String): String =
{
a.+(b).+(c)
}
closure($anonfun)
}
)
closure($anonfun)
}
)
closure($anonfun)
}
)
闭包更难理解,但它有括号。在解析器之后打印没有用。
只是为了比较这里是 IntelliJ Desugar Scala code...
输出(手动缩写 FQN)
def forWithIf(condition: Boolean) = {
val x = name(0)
.flatMap(((a) =>
(if (condition) {
name(1);
name(2)
} else {
name(100)
})
.flatMap(((b) =>
name(2)
.map(((c) => a.$plus(b).$plus(c)))))
));
println(x)
};
确认 som-snytt 的回答。