Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I specify multiple constructors in the case class?

Tags:

scala

I'm trying to create a case class with multiple constructors:

object App {
  def main(args: Array[String]) {
    val a = Something("abc", 100500, _ % 2 == 0)
    val b = Something(true, 10, 20)   
    println(s"$a - $b")
  }
}

case class Something(s: String, n: Int, p: Int => Boolean) {
  /*
  Additional constructor -- Wrong way! -- it is imposible to invoke it outside the class
  def this(b: Boolean, x: Int, y: Int) {
    this("", 0, (i: Int) => i % x + y == 0)
  }
  */
}

So far my code doesn't work:

Error:(10, 23) type mismatch;
 found   : Boolean(true)
 required: String
    val b = Something(true, 10, 20)
                      ^

To fix it I need to create a companion object to hold an apply function which represents a new constructor for Something class:

object Something {    
  def apply(b: Boolean, x: Int, y: Int) = {
    new Something(if (b) "" else "default", 0, _ => {
      (x + y) % 2 == 0
    })
  }   
}

It is inconvenient. Maybe there is some other way to place multiple constructors into the case class?

like image 911
Finkelson Avatar asked Dec 01 '22 13:12

Finkelson


1 Answers

Actually it works, but you have to use new as auxiliary constructors do not have apply generated for case class:

case class Something(s: String, n: Int, p: Int => Boolean) {
  def this(b: Boolean, x: Int, y: Int) {
    this("", 0, (i: Int) => i % x + y == 0)
  }
}

new Something(true, 5, 5) // Works

If you want Something(true, 5, 5) to work, you need to create companion object as you said. I think this is because otherwise case class won't be able to work with pattern matching as it is now, or it would have been much more complicated. And notice that pattern matching won't work in this case

Also remember that case class supports default constructors like case class Something(s: String = "default") this might help you, but it does not fix your example unfortunately

like image 154
Archeg Avatar answered Dec 04 '22 03:12

Archeg