我如何使用重载的case类构造函数仍然使用模式匹配?

viv*_*mar 2 scala overloading pattern-matching case-class

当我找到这个例子时,我试图学习模式匹配.似乎case类模式匹配不适用于重载的case类构造函数.

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")
  } 
Run Code Online (Sandbox Code Playgroud)

我收到编译错误"模式MyClass的参数错误(第一个:字符串,最后:字符串)在"案例MyClass(a)"行.我期望模式匹配适用于重载的构造函数,但它不能正常工作有人可以解释一下这种行为吗?

另外,我得到一个构造函数参数的错误结果.

 val myClassOne = new MyClass("a")      
  myClassOne match {
   case MyClass(a,b) => println("two constructor matched")
   case _ => println("Not matched")
  } 
Run Code Online (Sandbox Code Playgroud)

即使myClassOne只有一个agrument,这也会产生"两个匹配的构造函数" .请解释.

Ben*_*mes 17

要了解发生了什么,您需要知道案例类的模式匹配是一个被调用的方法的语法unapply.这在Scala:Extractor Objects中进行了解释.

使用REPL,您可以看到编译器已unapply在伴随对象上生成了一个方法,该方法MyClass对应于主构造函数的参数:

scala> MyClass.unapply _
res0: MyClass => Option[(String, String)] = <function1>
Run Code Online (Sandbox Code Playgroud)

但是编译器不会为您定义(使用this())的任何辅助构造函数生成提取器.如果你试图自己定义一个额外的unapply你会明白为什么 - 你不能用另一个具有完全相同参数(一个实例MyClass)的方法重载该方法.

当您使用辅助构造函数创建实例时new MyClass("a"),它仍然是完全构造的实例,MyClass因此生成的unapply方法仍然有效.在该模式case MyClass(a,b)将匹配a"a",而b"".