46

我不断得到

Forward reference extends over definition of value a

尝试编译我的应用程序(在 SBT 内部)时出错。

a只是,错误是通过在定义val a = ""之前访问(函数的)特定参数来触发的。a该参数是一个简单案例类类型,具有所有三个类型的字段(枚举值的 Option 的Option[...]2和 1)。Option[org.joda.time.DateTime]

“前向参考延伸到价值的定义”到底意味着什么?对抗它的方法是什么?

4

8 回答 8

50

错误消息意味着您有一个方法的前向引用,即您在定义它之前调用了一个方法,并且值的定义x出现在该前向引用和方法的定义之间。如果引用和被引用的方法定义之间没有值定义,则只有前向引用才是合法的。

于 2012-11-11T04:34:49.777 回答
16

基本上这是一个错误。

解决方法是在调用它之前声明一个方法。我不知道为什么。

def a(input: String){

}

val k = a("ravi")
于 2016-04-05T00:00:18.607 回答
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 与序列混淆,让它变得懒惰可以解决问题

我想答案可能为时已晚,而且由于我看不到您实际尝试做的事情,因此我不确定这是否可以解决问题。

于 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 回答
0

你应该检查你的进口。它必须从导入中导入变量名,变量名必须在导入到您的代码中的某个库中使用。删除导入。

于 2020-04-10T05:56:38.073 回答
0

在我的情况下,将 val 定义移到隐式 val 定义之后就足够了,不清楚为什么。分配给 val 定义的方法实际上是在实际调用它的方法之前定义的。

于 2021-11-23T13:58:15.220 回答