【问题标题】:Overriding equals method in Scala覆盖Scala中的equals方法
【发布时间】:2015-02-25 19:40:05
【问题描述】:

我有以下代码。编译时出现错误提示

value email is not a member of Player

class Player(email: String)
{
  override def equals(player: Any): Boolean = {
    player match {
      case p: Player => email.equals(p.email)
      case _ => false
    }
  }
}

我是一名尝试使用 Scala 的 Java 程序员,但无法弄清楚为什么会发生此错误(据我了解,电子邮件是播放器实例的成员)。谁能给出解释以及如何解决这个问题?

【问题讨论】:

标签: java scala equals


【解决方案1】:

不要使用普通类并编写自己的 equals 方法,而是使用 case 类,如下所示:

case class Player(email: String)

equals 和 hashCode 方法会自动为您生成。额外的好处是,如果您更改字段,equals/hashCode 可以保证保持同步。如果您要进行任何类型的序列化,大多数库无论如何都需要案例类。

【讨论】:

  • 电子邮件在这个case中自动生效
【解决方案2】:

email 只是一个构造函数参数,而不是类本身的成员。你可以在它前面加上val

class Player(val email: String) {
  override def equals(player: Any): Boolean = {
    player match {
      case p: Player => email.equals(p.email)
      case _ => false
    }
  }
}

为了完整起见,您还可以手动将email 设为Player 的成员:

class Player(e: String) {
  val email: String = e
  ...
}

或者一个 def(如果你出于某种原因想要的话):

class Player(e: String) {
   def email: String = e
   ...
}

正如@srgfed01 所述,您也可以在构造函数中包含访问修饰符。例如:

class Player(private val email: String) 

case 类会自动为您的类生成 getter,但默认情况下它们都是公共的。

我更喜欢将构造函数参数声明为类成员的第一种方法,因为它清晰、简洁并减少了代码混乱(想象一下,如果您有 10 个参数需要访问器)。

【讨论】:

  • 如果您不希望“电子邮件”可见,则为“私人验证”
  • 感谢您的回答。我有另一个问题。对我来说,似乎还有另一种选择,即向类添加一个私有方法,该方法返回构造函数参数的值。这和你建议的有什么区别?这个比那个好吗? class Player(p_email: String) { private def email:String = p_email override def equals(player: Any): Boolean = { player match { case p: Player => email.equals(p.email) case _ => false } } }
  • 似乎更长而没有好处,功能方面也一样。即使电子邮件是公开的,像这样的“信息隐藏”也没有意义,因为电子邮件是不可变的并且可以直接暴露。奇怪的想法:我在构造函数参数中也有一些私有 val 的问题,因为它看起来很奇怪来自 Java,但几年后我什至不再考虑它,我现在有意识地记得将某些东西设为私有 val因为这也是一个编译器错误,而从未考虑过它是一个不太好的解决方案。
  • 既然你问了:恕我直言,第一个更好有两个原因:更简洁,并且在运行时可能会更慢,因为它之间至少会有一个方法调用(但它将是内联的可能通过 JIT)。
  • @Can'tTell 唯一的区别是与Player(private val email: String),相同的方法/成员是编译器生成的。 def 可能会稍微慢一点.. 但你也可以这样做 private val.
猜你喜欢
  • 2014-05-27
  • 2011-04-17
  • 2020-01-30
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多