考虑案例类Person
case class Person(firstName: String, lastName: String, middleName: Option[String])
object Person {
def apply(firstName: String, lastName: String): Person = new Person(firstName, lastName, None)
def unapply(arg: Person): Option[(String, String)] = Some(arg.firstName, arg.lastName)
}
val person = Person("firstName", "lastName")
person match {
case Person(firstName, lastName) => Console.println(firstName + " " + lastName)
}
在与case类编译器的模式匹配中,我给出了一个错误:模式匹配中的参数数量错误,但是当我使用类而不是case类时,它的工作原理。
class Person(val firstName: String, val lastName: String, middleName: Option[String])
我在这里理解的是,我们不能为case类使用自己的自定义提取器,但可以使用自己的构造函数(apply)。请解释我这种奇怪的行为。
这是一个ScalaFiddle来测试:https://scalafiddle.io/sf/HvxvdAZ/0
答案 0 :(得分:6)
您的自定义 SELECT Cast(Convert(datetime,'15-05-2018 16:09:21',103) as datetime);
SELECT convert( varchar(20),Convert(datetime,'15-05-2018 16:09:21',103) ,120)
与自动生成的unapply
冲突,因为它具有相同的名称和相同的参数类型(只有返回类型不同)。因此,出于与
unapply
无效。此代码段会显示错误:
错误:方法u定义了两次; 冲突的方法u在第12:7行定义
因此,您要么必须使用自己的class A {
def u(i: Int): Int = i
def u(i: Int): String = "int" + i
}
(类似unapply
)定义单独的提取器对象,要么省略类声明中的object FirstLast { def unapply(...) ... }
。
单独的提取器对象
这是一个(在我看来相对优雅)的方式:
case
省略case class Person(
firstName: String,
lastName: String,
middleName: Option[String]
)
object Person {
def apply(
firstName: String,
lastName: String
): Person = new Person(firstName, lastName, None)
object FirstLast {
def unapply(arg: Person): Option[(String, String)] =
Some((arg.firstName, arg.lastName))
}
}
val person = Person("firstName", "lastName")
person match {
case Person.FirstLast(firstName, lastName) =>
Console.println(firstName + " " + lastName)
}
,实施自己的case
如果您想完全替换原来的unapply
,那么您可以这样做:
unapply
但同样,它只允许一个class Person(
val firstName: String,
val lastName: String,
val middleName: Option[String]
)
object Person {
def apply(
firstName: String,
lastName: String,
middleName: Option[String]
): Person = new Person(firstName, lastName, middleName)
def apply(
firstName: String,
lastName: String
): Person = new Person(firstName, lastName, None)
def unapply(arg: Person): Option[(String, String)] =
Some((arg.firstName, arg.lastName))
}
val person = Person("firstName", "lastName")
person match {
case Person(firstName, lastName) =>
Console.println(firstName + " " + lastName)
}
。使用单独的提取器来使用多个unapply
方法。
答案 1 :(得分:0)
这不是你问的问题,但是如果你想保留case class
,你可以做以下事情:
case Person(firstName, lastName, _) =>
为您不使用的每个参数添加下划线_
。