Что означает "Перемещение ссылки на определение значения" в Scala?
Я продолжаю получать
Forward reference extends over definition of value a
при попытке скомпилировать мое приложение (внутри SBT).
a
просто val a = ""
, ошибка запускается путем доступа к определенному параметру (функции) непосредственно перед определением a
. Параметр имеет тип простого класса case со всеми тремя полями типа Option[...]
(2 из Option[org.joda.time.DateTime]
и 1 опциона значения перечисления).
Что может означать "Пересылка ссылки на определение значения" вообще и какими могут быть способы борьбы с ней?
Ответы
Ответ 1
В зависимости от вашей версии скаляса были ошибки, при которых синтетические методы вызывают эту ошибку.
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
Сообщение об ошибке означает, что у вас есть прямая ссылка на метод, то есть вы вызываете метод до его определения и что определение значения x
появляется между этой прямой ссылкой и определением метода, Допустимо иметь прямые ссылки, если нет определения значения между ссылкой и указанным методом.
Ответ 3
Если он ссылается где-то, и scalac запутан с последовательностью, делая его ленивым, можно сделать трюк
Я предполагаю, что это может быть поздно для ответа, и поскольку я не вижу, что вы на самом деле пытаетесь сделать, я не уверен, что это решает его.
Ответ 4
В основном это ошибка.
Исправление состоит в том, чтобы объявить метод перед его вызовом. Я не знаю, почему.
def a(input: String){
}
val k = a("ravi")
Ответ 5
Пример ответа, полученного 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
определение решит проблему.
Ответ 6
Сообщение означает, что во время выполнения scala не удалось найти ссылку на метод, который вызывается в вашем методе.
Обычно это происходит, когда вы пытаетесь выполнить метод, и реализация вызванного метода выполняется после вызова метода.
как для ex:
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 _)