Overload constructor for Scala's Case Classes?
Asked Answered
G

2

113

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?

Gayla answered 8/3, 2010 at 11:4 Comment(0)
H
205

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)
Honky answered 8/3, 2010 at 12:15 Comment(7)
Very nice :) I was looking for something like fallback values in scala, is it new from 2.8 ? I didn't know :)Gayla
Yes, Named and Default parameters are new in Scala 2.8.Honky
Martin Odersky explains why the additional apply methods aren't added automatically: scala-lang.org/node/976Yale
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)Corvine
secondary constructorsHonky
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.Cesium
@Corvine 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: https://mcmap.net/q/76157/-how-to-override-apply-in-a-case-class-companionEscamilla
D
24

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)
Dinin answered 8/3, 2010 at 12:11 Comment(1)
That's not strictly true - you can declare it in the companion object as normalKayleen

© 2022 - 2024 — McMap. All rights reserved.