I was trying to learn pattern matching when I found this example. It seems that case class pattern matching is not working with overloaded case class constructors.
case class MyClass(var first:String, var last:String){
def this(first: String) = this(first, "")
override def toString = "First: "+ first + " Last:" +last
}
val myClassTwo = new MyClass("a", "b")
myClassTwo match {
case MyClass(a,b) => println("two constructor matched")
case MyClass(a) => println("one constructor matched")
case _ => println("Not matched")
}
I am getting compilation error "wrong number of arguments for pattern MyClass(first:String, last:String) at "case MyClass(a)" line. I was expecting pattern matching to work for the overloaded constructor, but it's not working as I expected. Could anyone please explain this behaviour?
Also I am getting wrong result with one constructor parameter.
val myClassOne = new MyClass("a")
myClassOne match {
case MyClass(a,b) => println("two constructor matched")
case _ => println("Not matched")
}
This produces "two constructor matched" even if myClassOne has only one agrument. Please explain.
To understand what's going on, you need to know that pattern matching on case classes is syntax for a method called unapply. This is explained in A Tour of Scala: Extractor Objects.
Using the REPL, you can see that the compiler has generated an unapply method on the companion object of MyClass, which corresponds to the parameters of the main constructor:
scala> MyClass.unapply _
res0: MyClass => Option[(String, String)] = <function1>
But the compiler will not generate extractors for any auxiliary constructors that you define (using this()). If you try to define an additional unapply yourself you'll see why - you can't overload the method with another that has exactly the same parameters (an instance of MyClass).
When you create an instance using the auxiliary constructor, new MyClass("a"), that is still a fully constructed instance of MyClass and hence the generated unapply method is still valid. The pattern in case MyClass(a,b) will match a to "a", and b to "".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With