2

当我发现这个例子时,我正在尝试学习模式匹配。似乎案例类模式匹配不适用于重载的案例类构造函数。

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")
  } 

我在“case MyClass(a)”行收到编译错误“模式 MyClass(first:String, last:String) 的参数数量错误。我期待模式匹配适用于重载的构造函数,但它不起作用,因为我预期。有人可以解释一下这种行为吗?

我也得到了一个构造函数参数的错误结果。

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

即使myClassOne只有一个参数,这也会产生“两个构造函数匹配”。请解释。

4

2 回答 2

17

要了解发生了什么,您需要知道案例类上的模式匹配是一种名为unapply. 这在A Tour of Scala: Extractor Objects中有解释。

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

scala> MyClass.unapply _
res0: MyClass => Option[(String, String)] = <function1>

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

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

于 2013-03-04T10:09:29.830 回答
3

本的答案是完美的..

您仍然可以case class通过使用_您不关心的参数来找到一种方法来匹配您的...

myClassOne match {
   case MyClass("a","b") => println("two constructor matched")
   case MyClass("a",_) => println("one constructor matched")
   case _ => println("Not matched")
  } 
于 2013-03-04T12:51:44.187 回答