Scala 实例变量最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4850295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala instance variables best practice
提问by halfwarp
How would one translate the following Java code to Scala?
如何将以下 Java 代码翻译成 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
}
What is recommended, and why?
推荐什么,为什么?
回答by Landei
There is no simple translation from Java to Scala, it depends on the context:
从 Java 到 Scala 没有简单的翻译,这取决于上下文:
- 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?
- Whyare 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?
- Java中的变量是可变的吗?如果是(否则它们在 Java 中应该是 final 的):在 Scala 中使它们不可变是否有意义?
- 构造函数应该在 Scala 中保持公开吗?工厂(例如伴随对象中的应用方法)会更合适吗?
- 为什么变量是私有的?他们有 getter 和/或 setter 吗?
- 什么时候需要变量,让它们变得懒惰有意义吗?
- 如果这些值是不可变的并且是公开的,它们在模式匹配中会有用吗?案例类会是正确的选择吗?
- 是否可以对变量进行分组(例如在元组中)以简化 API 和访问?
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.
你看,有这么多的考虑。我建议您了解 Scala 的可能性,并尝试不同的方法,否则您会陷入“Scala 作为更好的 Java”陷阱中的时间比需要的时间长。
回答by ziggystar
This is the most direct translation to Scala:
这是对 Scala 最直接的翻译:
class ClassA{
private var field1 = 1
private var field2 = 2
}
Note the usage of varinstead of val. valis an immutable field, corresponding to public finalin 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.
注意 的用法var而不是val。val是一个不可变字段,对应public final于Java中。因此,以后无法更改它,并且提供一种将此类字段初始化为给定实例的正确值的方法很重要。
In order to decide what you want to use you should ask yourself the questions that are listed in Landei's answer.
为了决定您想使用什么,您应该问自己 Landei 的回答中列出的问题。
回答by eivindw
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.
两者最大的区别在于类参数一可以作为构造函数。如果您希望构造函数没有参数,作为您的 Java 示例,那么您需要使用第二个参数,并按照@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)
回答by Debilski
If you want to have private fields, why not declare them private?
如果您想拥有私有字段,为什么不将它们声明为私有?
class ClassA {
private val field1: Int = 1
private val field2: Int = 2
}
回答by Nicolas
If you alwayswant 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:
如果您总是希望 field1 和 field2 对于 A 类的每个实例具有相同的值,我建议将它们放在一个配套模块中:
object A {
private val field1 = 1
private val field2 = 2
}
And then use them in class A:
然后在 A 类中使用它们:
class A {
def complexInternalComputation = 2*A.a
}
or this way:
或者这样:
class A {
import A._
def complexInternalComputation = 2*a
}

