简体   繁体   中英

How to initialize a field with more than one operation?

class A (names: String*) {
  val namesBuffer: ListBuffer[String] = new ListBuffer[String]
}

I was wondering, how I can add the names of the names array from the primary constructor argument to the namesBuffer field when creating the object ? Do I have to create an auxiliary construtor to do so or is there another way to tell Scala to do operations in the primary Constructor ?

Note: The example above is fictive, I just want to know, how I can tell the primary constructor to do some more operations than assigning fields.

Every statement in the body of the class definition becomes a part of the body of the default constructor.

In your example you can just do:

class A (names: String*) {
  val namesBuffer: ListBuffer[String] = new ListBuffer[String]
  namesBuffer ++= names
}

or shorter:

class A (names: String*) {
  val namesBuffer: ListBuffer[String] = new ListBuffer[String] ++= names
}

or:

class A (names: String*) {
  val namesBuffer: ListBuffer[String] = ListBuffer[String](names: _*)
}

As axel22's answer demonstrates, you can perform those operations anywhere in the body of the class.

But it is good practice IMO to initialize the field fully with a single expression.

When side effects are required, you can achieve this using curly braces to make a block, which is an expression having the value of the last line:

class A(names: String*) {
  val namesBuffer: ListBuffer[String] = {
    val buffer = new ListBuffer[String]
    buffer ++= names
    buffer
  }
}

With this technique, you ensure that no other initialization logic accesses the value of namesBuffer before you have finished initializing that.

In Scala the entire class definition is effectively the default constructor, if that makes sense.

You can do something like this:

class A (names: String*) {
  val namesBuffer: ListBuffer[String] = new ListBuffer[String]
  namesBuffer.add(names)
}

You could also initialize the names buffer if it took a string array:

class A (names: String*) {
  val namesBuffer: ListBuffer[String] = new ListBuffer[String](names)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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