John Threepwood
John Threepwood

Reputation: 16143

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.

Upvotes: 2

Views: 183

Answers (3)

Ben James
Ben James

Reputation: 125167

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.

Upvotes: 3

axel22
axel22

Reputation: 32335

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: _*)
}

Upvotes: 3

Noah
Noah

Reputation: 13959

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)
}

Upvotes: 0

Related Questions