46

私は得続けます

Forward reference extends over definition of value a

アプリケーションをコンパイルしようとしているときにエラーが発生しました (SBT 内)。

aはちょうど、エラーは定義val a = ""の直前に(関数の)特定のパラメーターにアクセスすることによってトリガーされます。パラメーターは、型の 3 つのフィールドすべて (列挙値の Option の2と 1)aを持つ単純なケース クラス型です。Option[...]Option[org.joda.time.DateTime]

「前方参照は値の定義を超えて拡張される」とはどういう意味ですか?それと戦う方法は何ですか?

4

8 に答える 8

50

エラー メッセージは、メソッドへの前方参照があること、つまりメソッドを定義する前にメソッドを呼び出していること、および値の定義がxその前方参照とメソッドの定義の間にあることを意味します。参照と参照されるメソッド定義の間に値の定義がない場合にのみ、前方参照を持つことは正当です。

于 2012-11-11T04:34:49.777 に答える
15

scalac のバージョンによっては、合成メソッドがこのエラーを引き起こすバグがありました。

https://issues.scala-lang.org/browse/SI-6278

図では、f が生成されると想像してください。

object Test {
  def main(args: Array[String]) {
    class NotUsed {val x = f}
    val dummy = false
    def f = true
  }
}

ケース クラス、デフォルト引数、および暗黙のクラスには、合成が含まれます。

そのチケットのサンプル コード (修正済み) では、関数の最後に暗黙を移動することで、ok メソッドを中断できます。

object tiny {

  def main(args: Array[String]) {
    ok(); nope()
  }
  def ok() {
    class Foo(val i: Int) {
      def foo[A](body: =>A): A = body
    }
    implicit def toFoo(i: Int): Foo = new Foo(i)

    val k = 1
    k foo println("k?")
    val j = 2
  }
  def nope() {
    implicit class Foo(val i: Int) {
      def foo[A](body: =>A): A = body
    }

    val k = 1
    k foo println("k?")
    //lazy
    val j = 2
  }
}

それと戦う方法は何ですか?

コード内のコメントが示すように、定義を遅延させることは回避策です。

図 2、関数が長すぎて命名の問題に気付かないことを想像してください。

object Test {
  def main(args: Array[String]) {
    class NotUsed {val xs = args}
    val dummy = false
    // oops, shadows the parameter
    def args = Seq("a","b","c")
  }
}
于 2012-11-11T05:56:04.080 に答える
10

それがどこかで参照されていて、scalac がシーケンスと混同されている場合は、lazy にすることでうまくいく可能性があります

答えが遅いかもしれませんが、あなたが実際に何をしようとしているのかわからないので、それが解決するかどうかはわかりません.

于 2013-03-01T14:02:05.690 に答える
2

sepp2k によって与えられた回答の例

object ForwardReferenceTest {

  def main(args: Array[String]): Unit = {
    test
    val x = 1
    def test = println("hi")
  }
}

エラーが発生します

Error:(7, 5) forward reference extends over definition of value x
    test
    ^

関数testは呼び出しの後に定義されx、その間に値の定義があります。定義を削除/移動val xすると問題が解決します。

于 2016-06-23T17:22:10.810 に答える
1

メッセージは、実行時に scala がメソッドで呼び出されたメソッドの参照を見つけることができなかったことを意味します。これは通常、メソッドを呼び出しようとして、呼び出されたメソッドの実装が呼び出し元のメソッドの後にある場合に発生します。

例のように:

implicit val userDetails: Reads[UserDetails] = (
          (JsPath \ "name").read[String] and
            (JsPath \ "providers").read[List[Provider]]
          )(UserDetails.apply _) 

implicit val providers: Reads[Provider] = (
          (JsPath \ "providerName").read[String] and
            (JsPath \ "providerUserId").read[String] and
            (JsPath \ "authtoken").read[String]
          )(Provider.apply _)

そしてそれへの正しい方法。

implicit val providers: Reads[Provider] = (
      (JsPath \ "providerName").read[String] and
        (JsPath \ "providerUserId").read[String] and
        (JsPath \ "authtoken").read[String]
      )(Provider.apply _)

     implicit val userDetails: Reads[UserDetails] = (
      (JsPath \ "name").read[String] and
        (JsPath \ "providers").read[List[Provider]]
      )(UserDetails.apply _)
于 2016-09-21T18:55:34.567 に答える