Reputation: 975
In a case class I had to change one argument the constructor from String
to Set[String]
.
For backwards compatibility I have now added a companion object with an overloaded apply function.
case class OldClass (x: String, y: Set[String] = Set()) {}
case class NewClass(x: Set[String], y: Set[String] = Set()) {}
object NewClass {
def apply(x: String): NewClass = NewClass(Set(x), Set[String]())
def apply(x: String, y: Set[String]): NewClass = NewClass(Set(x), y)
}
Now this works:
val c = NewClass("xxx", Set[String]())
But how can I make this work:
val c = NewClass("xxx", Set())
I need this, because I have some code that relies on being able to create a NewClass
like this
Im getting the Error:
overloaded method value apply with alternatives (x:String) <and> (x: String,y: Set[String]) cannot be applied to (String, scala.collection.immutable.Set[Nothing])
Upvotes: 0
Views: 48
Reputation: 962
The problem is that constructor Set()
yields a value of type Set[Nothing]
which is not Set[String]
. To make this work precisely as you want, you can use not very reliable but working approach by adding another constructor that actually allows Set[Nothing]:
case class NewClass(x: Set[String], y: Set[String]) {}
object NewClass {
def apply(x: Set[String]): NewClass = NewClass(x, Set.empty[String])
def apply(x: String): NewClass = NewClass(Set(x), Set[String]())
def apply(x: String, y: Set[String]): NewClass = NewClass(Set(x), y)
def apply(x: String, y: Set[Nothing], z: Unit = ()): NewClass = NewClass(Set(x), Set.empty[String])
}
val c = NewClass("xxx", Set())
Note that z: Unit = ()
default parameter added only and only to distinguish these two constructors after generics type erasure, and default parameter y = Set.empty[String]
was deleted because first constructor actually restores such syntax. I don't recommend using this approach in real code, because, well that's, a pretty counter-intuitive hack.
Upvotes: 2