Why this class is allowed in Scala 2.x and it complains of duplicated definition of a
under Scala 3?
class A private(a:Int) {
def a(): Int = this.a+1
}
Double definition:
private[this] val a: Int in class A at line 1 and
def a(): Int in class A at line 2
It this by design or it is a bug in Scala 3?
class A private(a: Int) {
def a(): Int = this.a + 1
}
TL;DR: In Scala 2 this creates a member and a method of A
which are both called a
, but Scala 3 doesn't allow this duplicate use of the same name.
In Scala 2 there is a member a
that contains the value that is passed to the constructor and a method a
that returns this.a + 1
. This can be shown by adding a second method b
:
class A(a: Int) {
def a(): Int = a + 1
def b(): Int = a() + 1
}
println(new A(3).a()) // 4
println(new A(3).a) // 4 with compiler warning about auto-application
println(new A(3).b()) // 5
Within the class you get different values for a
depending on whether or not it is used bare or invoked as a function. Method a
uses the member value a
while method b
uses the method value a
. Outside the class only the method is visible.
Note that this is specifically a problem with the behaviour of non-val
non-var
constructor parameters for a class
. If the constructor parameter is made val
or var
the compiler will flag this as a duplicate even in Scala 2.