How to define local var / val in the main constructor in Scala?

In Scala, the main class constructor does not have an explicit body, but is implicitly defined from the body of the class. How, then, to distinguish between fields and local values ​​(i.e., values ​​local to the constructor method)?

For example, take the following code snippet, a modified form of some sample code from "Programming in Scala":

class R(n: Int, d: Int) { private val g = myfunc val x = n / g val y = d / g } 

I understand that this will create a class with three fields: private "g" and publicly available "x" and "y". However, the value of g is used only to calculate the fields x and y and does not matter outside the scope of the constructor.

So, in this (supposedly artificial) example, how are you going to define local values ​​for this constructor?

+59
scala scala-primary-constructor
Jul 13 '09 at 10:17
source share
4 answers

eg.

 class R(n: Int, d: Int) { val (x, y) = { val g = myfunc (n/g, d/g) } } 
+37
Jul 13 '09 at 11:39
source share

There are several ways to do this. You can declare such temporary variables within private definitions that will be used during construction. You can use temporary variables inside blocks that return expressions (for example, in Alaz’s answer). Or, finally, you can use such variables inside alternative constructors.

Similar to alternative constructors, you can also define them inside the "apply" method of the companion object.

What you cannot do is declare the field "temporary."

Note also that any parameter received by the main constructor is also a field. If you do not want such parameters to become fields and do not want to set the actual fields in the constructor, the usual solution is to make the main constructor private with the actual fields and use either an alternative constructor or object-companion apply () as an effective "primary "constructor.

+16
Jul 13. '09 at 12:19
source share

Another option that we have is to make the primary constructor of objects closed and use the companion object method as applied to the builder. If we apply (no pun intended), this approach to your example would look like this:

 class R private (val x: Int, val y: Int); object R { def apply(n: Int, d: Int): R = { val g = myfunc; new R(n / g, d / g); } } 

To create an instance of R instead:

 val r = new R(1, 2); 

write:

 val r = R(1, 2); 

This is a bit verbose, but it could be worse, I think :). Let us hope that private [this] vals will be considered as temporary variables in future Scala releases. Martin himself hinted at it.

+11
Jan 28 '10 at 19:46
source share

Some discussion on this topic, including comments by Martin Odersky, is here

+6
Jul 13 '09 at 22:44
source share



All Articles