Oscar Godson
Oscar Godson

Reputation: 32716

How to define val inside class constructor in Scala

I'm trying ot define a val inside a Class' constructor but I'm not getting it to work. It's a fairly intense computation so I don't want to run it twice. I saw this the following link but when I try to do that with this code it doesnt work (i get "application does not take parameters" still): How do you define a local var/val in the primary constructor in Scala?

class MyModel(
  val foo: String,
  val bar: String,
  val baz: String,
) extends db.BaseModel {
  def this() = this(
    foo = "",
    bar = "",
    baz = ""
  )

  def this(
    foo: SomeModel,
    bar: String,
    baz: String,
  ) = {
    this(
      someModel.id,
      doSomeComplexComputation(),
      doSomeComplexComputation(),
    )
  }

I'd like to have something like:

class MyModel(
  val foo: String,
  val bar: String,
  val baz: String,
) extends db.BaseModel {
  def this() = this(
    foo = "",
    bar = "",
    baz = ""
  )

  def this(
    foo: SomeModel,
    bar: String,
    baz: String,
  ) = {
    val complexCalcSaved = doSomeComplexComputation()
    this(
      someModel.id,
      complexCalcSaved,
      complexCalcSaved,
    )
  }

But as I mentioned above I get "application does not take parameters". How do I go about this?

Upvotes: 1

Views: 686

Answers (2)

fcat
fcat

Reputation: 1251

I would recommend creating constructors in the companion object. In your case, such an implementation can work:

class MyModel(val foo: String, val bar: String, val baz: String) extends db.BaseModel

object MyModel {

//empty constructor
def apply(): MyModel = new MyModel("", "", "")

//another constructor
def apply(foo: SomeModel, bar: String, baz: String): MyModel = new MyModel(foo.id, doSomeComputation(bar), doSomeComputation(baz))
}

Now you can call the constructors:

//create a MyModel object with empty constructor
MyModel() 

//create a MyModel object with the second constructor
MyModel(someModel, "string1", "string2")

Upvotes: 4

Dmytro Mitin
Dmytro Mitin

Reputation: 51648

I would write this with companion object and apply method:

  class MyModel(
                 val foo: String,
                 val bar: String,
                 val baz: String,
               ) extends db.BaseModel 

  object MyModel {
    def apply(): MyModel = new MyModel("", "", "")
    def apply(foo: SomeModel,
              bar: String,
              baz: String): MyModel = {
      val complexCalcSaved = doSomeComplexComputation()
      new MyModel(someModel.id, complexCalcSaved, complexCalcSaved)
    }
  }

Upvotes: 1

Related Questions