考虑一个案例类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)
}
Run Code Online (Sandbox Code Playgroud)
在与case类编译器的模式匹配中给出了一个错误:模式匹配中的参数数量错误,但是当我使用类而不是case类时它的工作.
class Person(val firstName: String, val lastName: String, middleName: Option[String])
Run Code Online (Sandbox Code Playgroud)
我在这里理解的是,我们不能为case类使用自己的自定义提取器,但可以使用自己的构造函数(apply).请解释我这种奇怪的行为.
这是一个测试的ScalaFiddle:https://scalafiddle.io/sf/HvxvdAZ/0
您的自定义unapply与自动生成的冲突unapply因为它具有相同的名称和相同的参数类型(只有返回类型不同).所以,由于同样的原因,这是无效的
class A {
def u(i: Int): Int = i
def u(i: Int): String = "int" + i
}
Run Code Online (Sandbox Code Playgroud)
会无效的.此代码段会给出错误:
错误:方法u定义两次; 你在第12:7行定义了冲突的方法
因此,您要么必须使用自己的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)
}
Run Code Online (Sandbox Code Playgroud)
省略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)
}
Run Code Online (Sandbox Code Playgroud)
但同样,它只允许一个单一unapply.使用单独的提取器来使用多个unapply方法.
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |