当我找到这个例子时,我试图学习模式匹配。似乎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")
}
我收到编译错误“模式MyClass的参数错误(第一个:String,last:String)在”case MyClass(a)“行。我期望模式匹配适用于重载的构造函数,但它不是按照我的预期工作。有人可以解释一下这种行为吗?
另外,我得到一个构造函数参数的错误结果。
val myClassOne = new MyClass("a")
myClassOne match {
case MyClass(a,b) => println("two constructor matched")
case _ => println("Not matched")
}
即使myClassOne
只有一个agrument,这也会产生“两个匹配的构造函数”。请解释一下。
答案 0 :(得分: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
与""
匹配。
答案 1 :(得分:3)
Ben的答案很完美......
您仍然可以使用case class
找到与_
匹配的方法,以获取您不关心的参数...
myClassOne match {
case MyClass("a","b") => println("two constructor matched")
case MyClass("a",_) => println("one constructor matched")
case _ => println("Not matched")
}