What is the Scala equivalent of the `this` operator in Java?
In Java I'd normally initialize fields in a constructor in this way:
private double real;
private double imaginary;
public Complex(double real, double imaginary) {
this.real = real;
this.imaginary = imaginary;
}
Is there a way to do the same in Scala for classes or objects? Like instead of
class Complex开发者_运维问答(real: Double, imaginary: Double) {
def re = real
def im = imaginary
}
something like this:
class Complex(real: Double, imaginary: Double) {
def this.real = real
def this.imaginary = imaginary
}
Edit: whoops, I think I confused methods with fields here.
So far, nobody has directly answered your question. The Scala equivalent of the Java this
operator is (surprise!) the Scala this
operator. You did indeed confuse methods with fields in your example; your code would work as written if you replaced the def
s with val
s. However, as others have pointed out, you don't need this
here.
Additionally, Scala allows you to define an 'alias' for this
using the Explicitly Typed Self Reference syntax that Peter Schmitz demonstrated. The alias 'self' is frequently used, but any identifier is valid.
When you write
class Complex(real: Double, imaginary: Double)
in Scala you automatically create and initialize fields real
and imaginary
so in this case you don't need to use this
.
For this situation (immutable complex numbers) case classes are exactly what you would want to use. If you do want to initialize another field in a constructor you would do it like:
case class Complex(real: Double, imaginary: Double) {
val foo = "bar"
}
Now real, imaginary and foo are all public fields in Complex.
EDIT below -
Using a regular class you can make the constructor parameters public fields like:
class Complex(val real: Double, val imaginary: Double)
class MutableComplex(var real: Double, var imaginary: Double)
Here is something interesting that I did not know:
class Complex(real: Double, imaginary: Double) {
println(real + " + " + imaginary + "i")
}
% javap -private Complex
public class Complex extends java.lang.Object implements scala.ScalaObject{
public Complex(double, double);
}
real
and imaginary
are not in the class.
But if you use the constructor parameters outside the constructor, they get added as private vals:
class Complex(real: Double, imaginary: Double) {
override def toString = real + " + " + imaginary + "i"
}
% javap -private Complex
public class Complex extends java.lang.Object implements scala.ScalaObject{
private final double real;
private final double imaginary;
public java.lang.String toString();
public Complex(double, double);
}
In addition to the other answers: You can specify Explicitly Typed Self References, for example in case of identifier clash.
case class Complex(real: Double, imaginary: Double) { self =>
def +(real: Double, imaginary: Double) = Complex(self.real + real, self.imaginary + imaginary)
}
精彩评论