7

类似的问题1.2.提到了 scala 中前向引用的实际问题。但是我发现了这个没有前向引用的特殊简单案例。所有块都是完全独立的。

def testFunction() = {
  def recursiveMethod(i: Int, j: Int = 3): Unit = i match {
    case 0 => println(s"finished")
    case i => recursiveMethod(i-1)
  }
  val shapes = List[String]()
  def recursive(i: Int): Unit = i
}

迄今为止发现的解决该问题的解决方案:

  • shapes一个懒惰的 val(如2.
  • 将函数重命名recursive不是前缀的东西recursiveMethod
  • 去掉可选参数j:Int = 3
  • 没有recursiveMethod 调用本身

有人可以向我解释为什么这些是解决方案,尽管它们似乎与问题完全无关?

4

1 回答 1

5

-Xprint:typer可以看到前向引用的合成:

package oops {
  object Test extends scala.AnyRef {
    def <init>(): oops.Test.type = {
      Test.super.<init>();
      ()
    };
    def testFunction(): Unit = {
      def recursiveMethod(i: Int, j: Int = 3): Unit = i match {
        case 0 => scala.this.Predef.println(scala.StringContext.apply("finished").s())
        case (i @ _) => recursiveMethod(i.-(1), recursiveMethod$default$2)
      };
      val shapes: List[String] = immutable.this.Nil;
      def recursive(i: Int): Unit = {
        i;
        ()
      };
      <synthetic> def recursiveMethod$default$2: Int @scala.annotation.unchecked.uncheckedVariance = 3;
      ()
    };
    def main(args: Array[String]): Unit = ()
  }
}

至少有几张票与生成方法接近其起源相关,以避免这些看不见的问题。

更新:对于淫荡者:

虽然过时但好用

如果与此问题没有直接关系,请更贴近我的心

我特别喜欢“重命名函数,使其不是其他函数的前缀”。

这显示了重命名如何重新排序成员:

  abstract trait Oops extends scala.AnyRef {
    def /*Oops*/$init$(): Unit = {
      ()
    };
    def testFunction(): Unit = {
      def recursiveMethod(i: Int, j: Int = 3): Unit = i match {
        case 0 => scala.this.Predef.println(scala.StringContext.apply("finished").s())
        case (i @ _) => recursiveMethod(i.-(1), recursiveMethod$default$2)
      };
      <synthetic> def recursiveMethod$default$2: Int @scala.annotation.unchecked.uncheckedVariance = 3;
      val shapes: List[String] = immutable.this.Nil;
      def xrecursive(i: Int): Unit = {
        i;
        ()
      };
      ()
    }
  };

不用说,这一定是一个错误或回归。对?

更新:

事实上,排序测试是syntName.toString.startsWith,这就解释了为什么重命名另一个函数会有所不同。这显示了脆弱的名称修改漏洞无处不在。这就像白蚁每隔一段时间就会从木制品中弹出,提醒您在过去五年中它们已经损害了框架的结构完整性。

这是带有注释的代码[Martin] This is pretty ugly. 所以它不是未知的,只是需要有空闲时间的人。

于 2013-09-11T07:37:10.673 回答