Scala中的“前向引用扩展到值的定义”是什么意思?

时间:2012-11-11 04:09:47

标签: scala

我一直在

Forward reference extends over definition of value a
尝试编译我的应用程序时(在SBT内)

错误。

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

什么可以“转发参考延伸超过价值的定义”意味着什么,以及可以采取什么方式来对抗它?

7 个答案:

答案 0 :(得分:44)

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

答案 1 :(得分:12)

根据您的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")
  }
}

答案 2 :(得分:9)

如果在某处引用它并且scalac与序列混淆,那么使它变得懒惰可以做到这一点

我想可能会迟到一个答案,因为我看不到你实际上想要做什么,我不确定是否能解决它。

答案 3 :(得分:8)

基本上它是一个错误。

修复方法是在调用方法之前声明方法。我不知道为什么。

def a(input: String){

}

val k = a("ravi")

答案 4 :(得分:1)

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定义将解决问题。

答案 5 :(得分: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 _)

答案 6 :(得分:0)

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