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
}

これまでに見つかったその問題を克服するための解決策:

  • 怠惰shapesvalを作成します ( 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であり、他の関数の名前を変更すると違いが生じる理由を説明しています。これは、壊れやすい名前マングリングがどこにでもバグを漏らしていることを示しています。それはまるでシロアリが木工品から飛び出してくるようなもので、過去 5 年間でフレームの構造的完全性が損なわれたことを思い出させてくれます。

これはコメント付きのコードです。[Martin] This is pretty ugly. したがって、不明ではありません。暇な人が必要なだけです。

于 2013-09-11T07:37:10.673 に答える