【问题标题】:overloading unapply method in case classes: scala在案例类中重载 unapply 方法:scala
【发布时间】:2011-10-25 05:45:09
【问题描述】:

考虑以下代码:

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

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))
}

编译器仍然报错“无法解决重载的 unapply”

【问题讨论】:

    标签: scala


    【解决方案1】:

    你的 unapply 方法不能用于模式匹配

    它适用于

    def unapply(arg: <type to match>) : Option[(<matched fields types>)]
    

    (如果只有一个字段,则没有元组,如果没有字段,则为布尔值而不是 Option)。

    用户的标准不适用是(Scala 语言规范第 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)
    

    我猜你想要前一个。在这种情况下,您的应用和标准方法都是具有相同参数列表(一个用户参数)的两种方法,因此它们不兼容。这可能看起来有点不幸,因为当方法被称为提取器时,区别元素实际上是结果元组的大小,而不是参数的类型。

    但是,您的方法虽然作为提取器无效,但不会引起冲突。我在规范中找不到禁止它的东西。尽管如此,它还是没有用的,并且正确地不允许使用有用的方法。

    【讨论】:

    • 感谢您的详细解释!我的错..我在输入时错过了一些用法。我实际上正在寻找后一个(从字符串中提取用户)——上面的例子可能是对真实场景的过度简化。您提到区分元素实际上是元组的大小,我只是为了完成添加更多元组结果而尝试,但编译器并没有让步。知道为什么吗?
    • 你误解了我关于元组的大小。我很遗憾提取器的语法不允许这样做。但我确定它不会。另一方面,如果你想要一个字符串输入,我不明白为什么不允许它。我要做的是将提取器命名为其他名称。至少在示例中,用户非常具有误导性,我更喜欢object NameOfUser {def unapply(s: String): Option[User]...}。我不知道它在你的代码中是否有意义。
    • 是的,你是对的。我将提取器命名为其他名称。但是编译器的信息仍然没有意义。至少应该清楚为什么我不能重载 apply 以及冲突在哪里。
    【解决方案2】:

    您不能覆盖 unapply(尤其是)的原因很可能是它与由案例类的配套对象自动创建的签名具有相同的签名。请记住,函数的签名并未考虑其返回值以进行覆盖。

    【讨论】:

      猜你喜欢
      • 2017-06-23
      • 1970-01-01
      • 2019-10-13
      • 2018-12-10
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      相关资源
      最近更新 更多