考虑以下代码:
case class User(id: Int, name: String)
object User{
def unapply(str: String) = Some(User(0, str))
}
Scala抱怨“错误:无法解析重载的unapply;案例类User(id:Int,str:String)” 是不是可能超载不应用?
更新: 不适用较大的元组大小。
case class User(id: Int, str: String)
object User{
def unapply(s: String) = Some((User(0, s), s, 1234))
}
编译器仍然抱怨“无法解决重载unapply”
答案 0 :(得分:8)
您的unapply方法无法用于模式匹配
适用于
def unapply(arg: <type to match>) : Option[(<matched fields types>)]
(如果只有一个字段,则没有元组,如果没有字段,则为布尔而不是选项。)
用户的标准不适用是(The Scala Language Specification p.67)
def unapply(u: User) =
if (u eq null) None
else Some((u.id, u.name))
您想要的是匹配具有零ID的用户,如
user match {case User(name) => ....}
那将是
def unapply(u: User): Option[String] =
if(u eq null || u.id != 0) None
else Some(u.name)
如果你想要一个字符串可以作为用户匹配(这将是相当奇怪的)
def unapply(s: String): Option[User] = Some(User(0, s))
可以使用
"john" match case User(u) => ... // u is User(0, john)
我想你想要前者。在这种情况下,您的apply和标准的两个方法都具有相同的参数列表(一个User参数),因此它们不兼容。这可能被视为有点不幸,因为当方法被称为提取器时,区分元素实际上是结果元组的大小,而不是参数的类型。
但是,您的方法虽然无法作为提取器生效,但不会导致冲突。我在规范中找不到禁止它的东西。尽管如此,它仍然是无用的,并且正确的方法是不允许的。
答案 1 :(得分:2)
您无法覆盖unapply(特别是)的原因很可能是它与case类的companiation对象自动创建的签名相同。记住函数的签名没有考虑其覆盖的用途的返回值。