Overload constructor for Scala's Case Classes?

74,379

Solution 1

Overloading constructors isn't special for case classes:

case class Foo(bar: Int, baz: Int) {
  def this(bar: Int) = this(bar, 0)
}

new Foo(1, 2)
new Foo(1)

However, you may like to also overload the apply method in the companion object, which is called when you omit new.

object Foo {
  def apply(bar: Int) = new Foo(bar)
}

Foo(1, 2)
Foo(1)

In Scala 2.8, named and default parameters can often be used instead of overloading.

case class Baz(bar: Int, baz: Int = 0)
new Baz(1)
Baz(1)

Solution 2

You can define an overloaded constructor the usual way, but to invoke it you have to use the "new" keyword.

scala> case class A(i: Int) { def this(s: String) = this(s.toInt) }
defined class A

scala> A(1)
res0: A = A(1)

scala> A("2")
<console>:8: error: type mismatch;
 found   : java.lang.String("2")
 required: Int
       A("2")
         ^

scala> new A("2")
res2: A = A(2)
Share:
74,379

Related videos on Youtube

Felix
Author by

Felix

&lt;3 Scala Consider visiting my scala blog: A Scala from 0 to 1

Updated on July 08, 2022

Comments

  • Felix
    Felix almost 2 years

    In Scala 2.8 is there a way to overload constructors of a case class?

    If yes, please put a snippet to explain, if not, please explain why?

  • oxbow_lakes
    oxbow_lakes about 14 years
    That's not strictly true - you can declare it in the companion object as normal
  • Felix
    Felix about 14 years
    Very nice :) I was looking for something like fallback values in scala, is it new from 2.8 ? I didn't know :)
  • retronym
    retronym about 14 years
    Yes, Named and Default parameters are new in Scala 2.8.
  • Seth Tisue
    Seth Tisue about 14 years
    Martin Odersky explains why the additional apply methods aren't added automatically: scala-lang.org/node/976
  • HEX
    HEX over 10 years
    And how i can use local variables inside overloaded constructor? For example: def this(bar: Int) = { val test = 0; this(bar,test) } (this is doesn't work)
  • retronym
    retronym over 10 years
    secondary constructors
  • pferrel
    pferrel almost 10 years
    It seems that if your secondary constructor takes another instance of Foo, you must use the apply method above with the companion object. Otherwise you get an error trying to use the secondary constructor that indicates the compiler expects the primary.
  • chaotic3quilibrium
    chaotic3quilibrium over 9 years
    @HEX When defining a secondary constructor on a case class, you must immediately invoke this(...); you're prevented from doing any parsing/validating of the passed parameters. If you want/need to parse/validate, you must create an explicit companion object and introduce an appropriate apply method (same signature as your desired function). What I have found over time is to stay away from case class secondary constructors. It is way preferable to stick with adding apply methods to the companion object. Please see my related answer on another thread: stackoverflow.com/a/25538287/501113