Reputation: 8189
private def foo(a:A):B = a match{
case A(...) =>
val x = a.b //error: wrong forward reference a
...
}
Where b is not mentioned in A(...), if that matters.
I've tried my luck on Google, but I seem to find only posts of people having errors involving forward references but no explanation of what this particular error actually means.
Would appreciate it if somebody could help me out.
Upvotes: 15
Views: 18966
Reputation: 8390
Here is an attempt to explain what @User1291 had not with his/her answer.
I'm new to Scala and Java so the answer wasn't obvious to me. I was surprised to run into this error in my (simplified) code:
object Main {
val data = getData()
def getUser() = {
getUserFrom(data) // error: Wrong Forward Reference
}
}
Wrong Forward Reference is equivalent to Java's Illegal Forward Reference, which is a fancy way of saying you can't reference a value that isn't known at compile time. In this case, getData()
can only return value during run time, and referencing data
gave this error.
When I tried changing the code to reference a known string, as expected the error went away:
object Main {
val name = "PieOhPah"
def getUser() = {
getUserFrom(name)
}
}
Another way is to close over the value with a function and access it from inside since functions are not evaluated until runtime:
object Main {
val data = getData()
def getUser(userData: UserData) = {
getUserFrom(userData)
}
// Invoke the method later with `data`
print(getUser(data).name)
}
Upvotes: 5
Reputation: 8189
Well, don't I feel stupid now...
private def foo(a:A):B = a match{
case A(...) =>
val x = a.b //error: wrong forward reference a
...
val a = ... //<-- THAT's the reason for the error
...
}
So a simple rename will resolve the issue:
private def foo(aa:A):B = aa match{
case A(...) =>
val x = aa.b
...
val a = ...
...
}
Upvotes: 28
Reputation: 13985
The problem is that you are probably using pattern-matching in some wrong way. As... You have not provided complete code. I have no idea about what is that mistake.
I am sure there is a problem somewhere else as following code (which is almost same as what you have given ) works flawlessly,
scala> :pa
// Entering paste mode (ctrl-D to finish)
case class A( c: String ) {
val b: String = c
}
def demoA( a: A ): String = a match {
case A( iAmC ) => {
val x = a.b
x
}
}
// Exiting paste mode, now interpreting.
defined class A
demoA: (a: A)String
scala> val anA = A( "sdfsd" )
anA: A = A(sdfsd)
scala> demoA( anA )
res3: String = sdfsd
So... basically if you have a case class like following,
case class A( b: String, c: String )
Now following would have worked.
private def foo( a:A ): B = a match{
case A( iAmB, iAmC ) => {
// iAmB and iAmC have values of a.b and a.c repectively
...
}
}
In your case...your function clearly says that your a
is an instance of A
- def foo( a:A )
so... you really don't need to pattern match here.
private def foo( a:A ): B = {
// Now class A should have member b and c
val iAmB = a.b
val iAmC = a.c
...
}
Upvotes: 1