The following code is taken from Programming in Scala book by Martin Odersky et al. which defines a rational type:
class Rational(n: Int, d: Int) {
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
...
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
Here the value g is only used when the implicit constructor initializes fields numer and denom. Suppose programmer knows that it wont be used anywhere else. In the above case it is still accessible after construction of the Rational object. Which means it will also occupy space since is a private field rather than being a local variable to the constructor.
My question is how do I change this code so that g
is only used while construction and then thrown away?
In this case, how about something like this?
class Rational(n: Int, d: Int) {
require(d != 0)
val (numer, denom) = {
val g = gcd(n.abs, d.abs)
(n / g, d / g)
}
private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
EDIT: This also creates an extra field that holds a tuple, as shown by running javap
on the compiled class (thanks, Alexey):
public class Rational extends java.lang.Object implements scala.ScalaObject{
private final scala.Tuple2 x$1; // actually unwanted!
private final int numer;
private final int denom;
public int numer();
public int denom();
private int gcd(int, int);
public Rational(int, int);
}
In other cases, I sometimes use the locally
block to avoid turning every val
into a field:
class A {
locally {
val value1 = // ...
val value2 = // ...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With