How possible that the first is correct Scala code but the second won't even compile?
The one that does compile
object First {
class ABC(body: => Unit) {
val a = 1
val b = 2
println(body)
}
def main(args: Array[String]): Unit = {
val x = new ABC {
a + b
}
}
}
This one doesn't compile on Scala 2.11 and 2.12
object Second {
class ABC(body: => Int) {
val a = 1
val b = 2
println(body)
}
def main(args: Array[String]): Unit = {
val x = new ABC {
a + b
}
}
}
It's not strange at all. Let's look at the first example:
You declare your class
ABC
to receive a pass by name parameter that returnsUnit
and you think this snippet:is passing that
body
parameter, it isn't.What's really happening is:val x = new ABC(()) { a + b }
If you run that code you will see that
println(body)
prints () because you're not passing a value for yourbody
parameter, the compiler allows it to compile because as the scaladoc states there is only 1 value of typeUnit
:Since there is only one value the compiler allows you to omit it and it will fill in the gap. This doesn't happen with singleton objects because they don't extend
AnyVal
. Just has the default value forInt
is0
the default value forUnit
is()
and because there is only this value available the compiler accepts it.From documentation:
Singleton objects don't extend
AnyVal
so they don't get treated the same.When you use syntax like:
You're merely adding things to the constructor body, you are not passing parameters.
The second example doesn't compile because the compiler cannot infer a default value for
body: => Int
thus you have to explicitly pass it.Conclusion
Code inside brackets to a constructor is not the same as passing a parameter. It might look the same in same cases, but that's due to "magic".