Вопрос по – Scala: игнорировать поле класса регистра для equals / hascode?

34

Можно ли игнорировать поле класса case в методе equals / haschode класса case?

Мой вариант использования состоит в том, что у меня есть поле, которое по сути является метаданными для остальных данных в классе.

Если перезаписать хэш-код / равно? user unknown

Ваш Ответ

4   ответа
79

ства и хеширования.

scala> case class Foo(a: Int)(b: Int)
defined class Foo

scala> Foo(0)(0) == Foo(0)(1)
res0: Boolean = true

scala> Seq(0, 1).map(Foo(0)(_).hashCode)
res1: Seq[Int] = List(-1669410282, -1669410282)

UPDATE

Выставлятьb как поле:

scala> case class Foo(a: Int)(val b: Int)
defined class Foo

scala> Foo(0)(1).b
res3: Int = 1
+1, круто! Не знал об этом.
@KenBloom, если вы добавите & quot; val & quot; до "b" это будет работать: case class Foo (a: Int) (val b: Int)
НоFoo(0)(0).b не работает. Выдает ошибкуvalue b is not a member of Foo.
2

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Person( val name:String, val addr:String) {
  override def equals( arg:Any) = arg match {
    case Person(s, _) => s == name
    case _ => false
  }
  override def hashCode() = name.hashCode
}

// Exiting paste mode, now interpreting.

scala> Person("Andy", "") == Person("Andy", "XXX")
res2: Boolean = true

scala> Person("Andy", "") == Person("Bob", "XXX")
res3: Boolean = false
Не очень привлекательный вариант, как.equals is hard to get right, а также.equals а также.hashCode вместе сделать много шаблонного.
Я бы сказал, что легко ошибиться, а не трудно понять, если это имеет смысл :) Обновился до чего-то более правильного
Согласитесь, что равный / hashCode overrighting подвержен ошибкам (как в java), просто посмотрите пример кода для примера. Однако все другие методы apply / unapply / toString / etc будут сгенерированы автоматически и будут работать как прежде.
0

toString в базовом классе он не будет переопределен производными классами дел. Вот пример:

sealed abstract class C {
  val x: Int
  override def equals(other: Any) = true
}

case class X(override val x: Int) extends C

case class Y(override val x: Int, y: Int) extends C

Чем мы тебя тестируем:

scala> X(3) == X(4)
res2: Boolean = true

scala> X(3) == X(3)
res3: Boolean = true

scala> X(3) == Y(2,5)
res4: Boolean = true
5

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Foo private(x: Int, y: Int) {
  def fieldToIgnore: Int = 0
}

object Foo {
  def apply(x: Int, y: Int, f: Int): Foo = new Foo(x, y) {
    override lazy val fieldToIgnore: Int = f
  }
}

// Exiting paste mode, now interpreting.

defined class Foo
defined module Foo

scala> val f1 = Foo(2, 3, 11)
f1: Foo = Foo(2,3)

scala> val f2 = Foo(2, 3, 5)
f2: Foo = Foo(2,3)

scala> f1 == f2
res45: Boolean = true

scala> f1.## == f2.##
res46: Boolean = true

.toString если необходимо.

Похожие вопросы