In Scala, how does one define a local parameter in the primary constructor of a class that is not a data member and that, for example, serves only to initialize a data membe
You can create temporary variables throughout the initialization of single class members like this:
class A(b:Int){
val m = {
val tmp = b*b
tmp+tmp
}
}
After some experimentation, I determined that simply leaving out var
or val
in front of the parameter b
will make it a local parameter and not a data member:
class A(var a: Int)
class B(b: Int) extends A(b)
Java expansion:
$ javap -private B
Compiled from "construct.scala"
public class B extends A implements scala.ScalaObject{
public B(int);
}
$ javap -private A
Compiled from "construct.scala"
public class A extends java.lang.Object implements scala.ScalaObject{
private int a;
public A(int);
public void a_$eq(int);
public int a();
public int $tag() throws java.rmi.RemoteException;
}
Notice that class A
has a private data member a
due to the var a: Int
in its primary constructor. Class B
, however, has no data members, but its primary constructor still has a single integer parameter.
Derek,
If you have this:
class A(a: Int) {
val aa = a // reference to constructor argument in constructor code (no problem)
def m: Float = a.toFloat // reference to constructor argument in method body (causes a to be held in a field)
}
you'll find (using javap, e.g.) that a field named "a" is present in the class. If you comment out the "def m" you'll then see that the field is not created.
If you remove the "var" or "val" keyword from the constructor parameter, it does not produce a property.
Be aware, though, that non-var, non-val constructor parameters are in-scope and accessible throughout the class. If you use one in non-constructor code (i.e., in the body of a method), there will be an invisible private field in the generated class that holds that constructor parameter, just as if you made it a "private var" or "private val" constructor parameter.
Addendum (better late than never??):
In this code the references to the constructor parameter occur only in the constructor body:
class C1(i: Int) {
val iSquared = i * i
val iCubed = iSquared * i
val iEven = i - i % 2
}
... Here the value i
exists only during the execution of the constructor.
However, in the following code, because the constructor parameter is referenced in a method body—which is not part of the constructor body—the constructor parameter must be copied to a (private) field of the generated class (increasing its memory requirement by the 4 bytes required to hold an Int
):
class C2(i: Int) {
val iSquared = i * i
val iCubed = iSquared * i
val iEven = i - i % 2
def mod(d: Int) = i % d
}