开发者

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 defs with vals. 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)
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜