我有一个从字符串中提取对象的提取器。
case class ItemStructure(id: String, data: String)
object ItemStructure {
def unapply(str: String): Option[ItemStructure] = {
str.split('-').toList match {
case List(id, data) => Some(ItemStructure(id, data))
case _ => None
}
}
}
如果我尝试在模式匹配中使用此提取器,则所有提取器都按预期工作。
"" match {
case ItemStructure(item) =>
}
它也适用于匹配匿名函数的模式。
Option("").map {
case ItemStructure(item) =>
}
现在,如果我尝试在部分函数中使用此提取器,编译器将失败并显示以下消息:无法解析重载的unapply
val func: PartialFunction[Any, Unit] = {
case ItemStructure(item) =>
}
如果我重命名unapply函数所在的伴随对象,则所有对象都按预期工作。
有人可以解释为什么如果提取物位于伴侣对象中,它不起作用吗?
答案 0 :(得分:4)
有两种ItemStructure.unapply
方法:由case类创建的方法和您自己创建的方法。前者采用ItemStructure
类型的参数,后者采用String
类型的参数。
在前两个示例中,匹配对象的类型为String
,因此只能应用第二个unapply
方法,并且不存在歧义。但在最后一个示例中,两个unapply
方法都符合条件,因此Scala不知道使用哪个方法。
如果您将unapply
方法放在除了伴随对象之外的其他位置,则不再有两个unapply
方法 - 只有您自己的方法(因为另一个方法仍然存在于伴随对象中)。这样可以解决歧义:ItemStructure.unapply
明确指的是自动生成的unapply
和NewName.unapply
明确指的是你的。
答案 1 :(得分:2)
使用Any
作为结果类型编译器无法确定取消应用函数的位置。您的unappl
y仅定义String
类型的行为。
这会有效:
val func: PartialFunction[String, Unit] = {
case ItemStructure(item) =>
}
否则尝试定义采用Any
类型的unapply函数。