在case类中重载unapply方法:scala

Aja*_*jay 6 scala

考虑以下代码:

case class User(id: Int, name: String)
object User{
  def unapply(str: String) = Some(User(0, str))
}
Run Code Online (Sandbox Code Playgroud)

Scala抱怨"错误:无法解决重载unapply;案例类User(id:Int,str:String)"是否无法重载unapply?

更新:取消应用更大的元组大小.

case class User(id: Int, str: String)
object User{
  def unapply(s: String) = Some((User(0, s), s, 1234))
}
Run Code Online (Sandbox Code Playgroud)

编译器仍然抱怨"无法解决重载unapply"

Did*_*ont 8

您的unapply方法无法用于模式匹配

它适用于

def unapply(arg: <type to match>) : Option[(<matched fields types>)]
Run Code Online (Sandbox Code Playgroud)

(如果只有一个字段,则没有元组,如果没有字段,则为布尔而不是选项).

用户的标准不适用(Scala语言规范第67页)

def unapply(u: User) = 
  if (u eq null) None 
  else Some((u.id, u.name))
Run Code Online (Sandbox Code Playgroud)

它你想要的是匹配一个零id的用户,如

user match {case User(name) => ....}
Run Code Online (Sandbox Code Playgroud)

那会是

def unapply(u: User): Option[String] = 
  if(u eq null || u.id != 0) None 
  else Some(u.name)
Run Code Online (Sandbox Code Playgroud)

如果你想要一个字符串可以作为用户匹配(这将是相当奇怪的)

def unapply(s: String): Option[User] = Some(User(0, s))
Run Code Online (Sandbox Code Playgroud)

它可以使用

"john" match case User(u) => ... // u is User(0, john)
Run Code Online (Sandbox Code Playgroud)

我猜你想要前者.在这种情况下,您的apply和标准的两个方法都具有相同的参数列表(一个User参数),因此它们不兼容.这可以被看作是一点点不幸,当方法被称为提取器,识别元件实际上是结果元组的大小,而不是的参数的类型.

但是,您的方法虽然不能作为提取器使用,但不会导致冲突.我在规范中找不到会禁止它的东西.尽管如此,它仍然是无用的,并且正确的方法是不允许的.

  • 你误解了元组的大小.我很遗憾提取器的语法不允许这样做.但我确信它没有.另一方面,如果你想要一个String输入,我不明白为什么不允许它.我要做的是将提取器命名为其他东西.在至少该示例中,用户是非常误导,我宁愿`对象NameOfUser {DEF取消应用(一个或多个:字符串):选项[用户] ...}`.我不知道你的代码是否有意义. (2认同)