简体   繁体   English

Scala:在构造函数外部的类中初始化val

[英]Scala: Initialize vals in a class outside the constructor

In Java, I know it is bad to define constructors or methods which have more than 4 or 5 parameters. 在Java中,我知道定义具有4个或5个以上参数的构造函数或方法是很不好的。

In Scala, using val over var is preferred. 在Scala中,首选使用val不是var

I have classes which have a lot of fields (like 7 fields or 10 fields). 我有很多字段的类(例如7个字段或10个字段)。 Most of the fields are not changed after the instantiation. 实例化后,大多数字段都不会更改。 So I'm trying to use val s for those fields. 所以我正在尝试对这些字段使用val However, the only way to initialize val s in a class that I can think up is passing them to the primary constructor. 但是,我可以想到的在类中初始化val的唯一方法是将它们传递给主构造函数。

class Person(
    val name: String,
    val gender: String,
    val age: Int,
    val height: Double,
    val weight: Double,
    val birthday: Date,
    val address: String) {
  def printInfo(): Unit = {
  ...
  }
  ...
}

But in this way, the primary constructor looks ugly. 但是这样,主构造函数看起来很丑陋。 Not only its definition, but also calling the constructor is. 不仅它的定义,而且调用构造函数。

val person = new Person(
  parser.getName(), parser.getGender(), parser.getAge(), ..., parser.getAddress())

This does not look good. 这看起来不太好。

If they were var s, I could use other methods to set them. 如果它们是var ,我可以使用其他方法来设置它们。 However, now they are val s, so they cannot be changed later. 但是,现在它们是val ,因此以后无法更改。

Is there any better way other than using the primary constructor? 除了使用主要构造函数之外,还有其他更好的方法吗? Or should I use var s in this case? 还是在这种情况下应该使用var

Sometimes, formatting (and maybe a bit of aliasing) can make a world of difference. 有时,格式化(也许有点混叠)可能会有所作为。 Add a sprinkling of named parameters then bake on medium for 20 minutes... 添加一些命名参数,然后在介质上烘烤20分钟...

The world can be your oyster: 世界可以成为您的牡蛎:

case class Person(
  name     : String,
  gender   : String,
  age      : Int,
  height   : Double,
  weight   : Double,
  birthday : Date,
  address  : String
) {
  ...
}

val p = parser

val person = Person(
  name    = p.getName(),
  gender  = p.getGender(),
  age     = p.getAge(),
  ...
  address = p.getAddress()
)

Use the builder pattern. 使用构建器模式。 A builder can use var to keep track of the data that is going to be used to initialize, and then the class can be initialized at once. 生成器可以使用var来跟踪将用于初始化的数据,然后可以立即初始化该类。 It will still have all these parameters, but you hide their usage from view by the builder. 它仍将具有所有这些参数,但是您会在构建器的视图中隐藏其用法。

You can even go further and have type safe builders, but that's an advanced technique and its added complexity is usually not worth the gain. 您甚至可以走得更远,并拥有类型安全的构建器,但这是一种高级技术,其增加的复杂性通常不值得。

您可以让Person类的构造函数获取一个解析器,并在类内部执行“获取”逻辑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM