开发者

Scala instance variables best practice

开发者 https://www.devze.com 2023-02-07 10:47 出处:网络
How would one translate the following Java code to Scala? class ClassA { private int field1; private int field2;

How would one translate the following Java code to Scala?

class ClassA {
    private int field1;
    private int field2;

    public ClassA() {
        field1 = 1;
        field2 = 2;
    }
}

I can see two options:

class ClassA(val field1: Int, val field2: Int) {
   ....
}

Or

class ClassA {
   val field1: Int = 1
   val field2: Int = 2
}

Wh开发者_如何学运维at is recommended, and why?


There is no simple translation from Java to Scala, it depends on the context:

  • Are the variables mutable in Java? If yes (else they should be final in Java): Would it make sense to make them immutable in Scala?
  • Should the constructor stay public in Scala? Would be a factory (e.g. an apply method in the companion object) more apropriate?
  • Why are are the variables private? Do they have getters and/or setters?
  • When are the variables needed, would it make sense to make them lazy?
  • If the values are immutable and exposed, would they be useful in pattern matching? Would a case class be the right choice?
  • Could the variables be grouped (e.g. in a tuple) in order to simplify API and access?

You see, there are so many considerations. I'd suggest to learn about the possibilities of Scala, and to play around with different approaches, else you get stuck in the "Scala as better Java" trap longer than needed.


This is the most direct translation to Scala:

class ClassA{
  private var field1 = 1
  private var field2 = 2
}

Note the usage of var instead of val. val is an immutable field, corresponding to public final in Java. Thus it cannot be changed later and providing a way to initialize such a field to the correct value for a given instance is important.

In order to decide what you want to use you should ask yourself the questions that are listed in Landei's answer.


The biggest difference between the two is that the class parameter one can be used as constructor. If you want the constructor to have no parameters, as your Java example, then you need to use the second one, plus adding the private modifier as suggested by @Debilski.

Another option would be to use default parameters in the constructor. That way the fields could be changed if needed:

class ClassA (private val field1: Int = 1, private val field2: Int = 2)

// Using defaults
val a = new ClassA

// Setting new values
val b = new ClassA(3, 4)


If you want to have private fields, why not declare them private?

class ClassA {
  private val field1: Int = 1
  private val field2: Int = 2
}


If you always want that field1 and field2 have the same value for each instance of the class A, I would suggest to put them in a companion module:

object A {
  private val field1 = 1
  private val field2 = 2
}

And then use them in class A:

class A {
  def complexInternalComputation = 2*A.a
}

or this way:

class A {
  import A._
  def complexInternalComputation = 2*a
}
0

精彩评论

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

关注公众号