gpt4 book ai didi

scala - 案例类的自定义提取器在模式匹配中不起作用

转载 作者:行者123 更新时间:2023-12-01 09:45:10 26 4
gpt4 key购买 nike

考虑一个案例类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)
}

在与案例类编译器的模式匹配中给我一个错误:模式匹配中的参数数量错误但是当我使用一个类而不是案例类时它可以工作。

class Person(val firstName: String, val lastName: String, middleName: Option[String])

我在这里的理解是,我们不能对案例类使用自己的自定义提取器,但可以使用自己的构造函数(应用)。请解释一下这种奇怪的行为。

这是一个 ScalaFiddle 来测试:https://scalafiddle.io/sf/HvxvdAZ/0

最佳答案

您的自定义 unapply 与自动生成的 unapply 冲突,因为它具有相同的名称和相同的参数类型(仅返回类型不同)。所以,这是无效的,原因与

class A {
def u(i: Int): Int = i
def u(i: Int): String = "int" + i
}

无效。此代码段会给出错误:

error: method u is defined twice; the conflicting method u was defined at line 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)
}

省略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。使用单独的提取器拥有多个 unapply 方法。

关于scala - 案例类的自定义提取器在模式匹配中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50350079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com