Reputation: 61
case class Test(kind: Int) {
val ifX = if (isX) "is X" else "not X"
val isX = kind == 1
}
val test = Test(1)
println("ifX=%s, isX=%b".format(test.ifX, test.isX))
Why this code print: ifX=not X, isX=true
When is move "val ifX" before "ifX" it's ok (print ifX=is X)
EDIT: I know how to fix that. I can't understand why compiler not issue warning or error in this situation.
Upvotes: 3
Views: 182
Reputation: 297155
OMG, I wonder how many times we'll go through this...
It's not possible to statically detect incorrectly used forward references in all cases in something better than exponential time. Or, if it is, it's complex enough that no one has done it.
This particular case is simple enough -- there's no inheritance, no traits being extended, no early initializers, no method being called, no closures, no functions, no nothing. It's simple enough that a warning may be added in the future.
You can catch it at run-time, and Scala provides the -Xcheckinit
flag for that.
By the way, you can get the exact same problem in Java, though it does warn you in this particular case.
Upvotes: 7
Reputation: 51319
You are making the assumption that order doesn't matter in scala. It does. Because isX is a variable value, and while it's defined when ifX runs, it's value is still uninitialized, and so it is the default for its type (boolean, so false).
If you redefine isX as a function (def isX = ...
) it would work.
This is roughly equivalent to the following Java:
class Test {
String ifX;
bool isX; // Defaults to false, its a primitive after all
public Test(Int kind) {
ifX = isX ? "is X" : "not X";
isX = kind == 1;
}
}
Upvotes: 7
Reputation: 2710
As Chris Shain pointed out isX
is not defined yet. I just want to add that it's not a variable, but a value, which means that you can actually make it lazy. A lazy value is only instantiated when you need it. Both ifX
and isX
could be made lazy in theory. Try something like this:
case class Test(kind: Int) {
val ifX = if (isX) "is X" else "not X"
lazy val isX = kind == 1
}
That should give the desired output.
Upvotes: 7
Reputation: 11285
well, isX is undefined when the class is ran the first time. Can you just switch both lines ?
Upvotes: 1