Scala实例变量最佳实践

16

如何将以下 Java 代码翻译成 Scala?

class ClassA {
    private int field1;
    private int field2;

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

我看到有两个选项:

class ClassA(val field1: Int, val field2: Int) {
   ....
}
或者
class ClassA {
   val field1: Int = 1
   val field2: Int = 2
}

什么是推荐的,以及为什么?


两个版本并不相等,因为Java版本中这两个字段是私有的,而你展示的Scala替代方案中这两个字段是公共的。也许你想更具体地说明你想要实现什么? - Daniel C. Sobral
5个回答

20

从Java到Scala的转换并没有简单的翻译, 它取决于上下文:

  • Java中的变量是否可变?如果是(否则它们应该在Java中是final):在Scala中将它们变成不可变会有意义吗?
  • 构造函数在Scala中是否应该保持为public?一个工厂方法(例如伴生对象中的apply方法)是否更适合?
  • 变量为什么要是私有的?它们有getter和/或setter吗?
  • 在何时需要这些变量,将它们变成lazy的会有意义吗?
  • 如果值是不可变的并且暴露了出去,它们是否有用于模式匹配? case类是否是正确的选择?
  • 变量能否被分组(例如在元组中),以简化API和访问?

你看,有很多要考虑的因素。我建议学习Scala的可能性,并尝试不同的方法,否则你会陷入“Scala比Java更好”的陷阱中更长的时间。


10

这是最直接的Scala翻译:

class ClassA{
  private var field1 = 1
  private var field2 = 2
}
注意使用var而不是valval是一个不可变的字段,对应于Java中的public final。因此,它不能在以后更改,为给定实例初始化此类字段的正确值的方法很重要。
为了决定你想要使用什么,你应该问自己列在Landei答案中的问题。

Java的私有变量是类私有的,而不是实例私有的,因此您应该删除[this]。 - Submonoid
@Submonoid 谢谢。看来我一直都做错了。 :) - ziggystar

7
两者最大的不同在于,class参数可以用作构造函数。如果你想要构造函数没有参数,就像Java示例一样,那么你需要使用第二个选项,并像@Debilski建议的那样添加private修饰符。
另一个选择是在构造函数中使用默认参数。这样,如果需要,字段可以更改:
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)

这是一个不错的解决方案,但并不等同于原帖中的Java代码。 - Raphael
@Raphael 那是真的。但是,由于所给出的Java示例本身似乎相当无意义,我认为展示一些选项可能会很有趣 :) - eivindw

5

如果您想要私有字段,为什么不声明它们为私有的呢?

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

1
如果您希望类A的每个实例中field1和field2始终具有相同的值,我建议将它们放在一个伴随模块中:
object A {
  private val field1 = 1
  private val field2 = 2
}

然后在A类中使用它们:

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

或者这样:

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

这个不行;从类A的实例中无法访问A.a,因为它是私有的。 - Raphael
从scala规范,§5.2节:•私有修饰符可以与模板中的任何定义或声明一起使用。这些成员只能从直接封闭的模板及其伴生模块或伴生类(§5.4)中访问。 - Nicolas
好的,那我只是在REPL中尝试了一下,抱歉。(我想撤销踩踏,但它不让我...) - Raphael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接