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

Iva*_*van 39 scala

我一直在

Forward reference extends over definition of value a
Run Code Online (Sandbox Code Playgroud)

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

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

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

sep*_*p2k 48

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

  • 你能提供一个有效的前向参考的例子吗? (2认同)

som*_*ytt 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
  }
}
Run Code Online (Sandbox Code Playgroud)

案例类,默认参数和隐式类涉及合成.

在该票证的示例代码中(已修复),您可以通过将隐式移动到函数末尾来中断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
  }
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以对抗它?

正如代码中的注释所暗示的那样,使定义变得懒惰是一种解决方法.

图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")
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我发现了实际的问题原因(感谢IntelliJ Idea在按住Ctrl并将鼠标悬停在值使用上时显示值声明)!具有相同名称的val(如函数参数)稍后在同一函数中声明.所以它不是编译器错误,它是我的一个错误. (7认同)

小智 11

基本上这是一个错误.

修复是在调用它之前声明一个方法.我不知道为什么.

def a(input: String){

}

val k = a("ravi")
Run Code Online (Sandbox Code Playgroud)

  • 或者让值变得懒惰 (2认同)

小智 9

如果在某处引用它并且scalac与序列混淆,那么使它变得懒惰就可以解决问题

我想这可能是迟到的答案,因为我无法看到你实际上想要做什么我不确定是否能解决它.