【问题标题】:Problem in scala for-comprehension de-sugar?scala中的问题理解脱糖?
【发布时间】:2020-02-20 19:51:20
【问题描述】:

我有以下理解,我使用命令scala -Xprint:parser ForComprehensionDemo.scala 去糖。当我复制去糖方法并调用它时,它会产生与理解不同的结果。知道为什么吗?

为了理解:

    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 )

【问题讨论】:

  • 什么是name?诊断"called for" 放在哪里?
  • @jwvh 不好意思,第一次忘记加了,刚刚编辑加了。

标签: scala for-comprehension scalac


【解决方案1】:

只是漂亮打印机中的一个错误。 if-else 周围缺少括号。

一般来说,scala 2 不能非常忠实地表示括号,但 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)
            }
          )

闭包更难以理解,但它有括号。解析器后打印没有用。

【讨论】:

    【解决方案2】:

    此处仅用于比较是 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 的回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-29
      • 2013-10-05
      • 2012-05-28
      • 2011-08-31
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2019-06-01
      相关资源
      最近更新 更多