2012-04-29 8 views

Respuesta

74

Solo los parámetros en la sección del primer parámetro se consideran para igualdad y hash.

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) 

ACTUALIZACIÓN

Para exponer b como un campo:

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

scala> Foo(0)(1).b 
res3: Int = 1 
+1

Pero 'Foo (0) (0) .b' no funciona. Da el error 'value b no es miembro de Foo'. –

+1

+1, genial! No sabia sobre esto. – missingfaktor

+2

@KenBloom si agrega "val" antes de "b" funcionará: clase de caso Foo (a: Int) (val b: Int) – czajah

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 

Puede omitir .toString si es necesario.

2

Puede anular los métodos equals y hasCode en una clase caso

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 
+1

No es una opción muy atractiva ya que ['.equals' es difícil de obtener a la derecha] (http://www.artima.com/lejava/articles/equality.html), y '.equals' y' .hashCode' juntos hacen un montón de repetición. – missingfaktor

+0

acepta que la corrección de igual/código hash es propensa a errores (como en java), solo mira el código de ejemplo para un ejemplo. Sin embargo, todos los demás métodos, apply/unpply/toString/etc se generarán automáticamente y funcionarán como antes. – andy

+0

Yo diría que es fácil equivocarse, en lugar de serlo, si tiene sentido :) Haber actualizado a algo más correcto –

0

Si anulación toString en la clase base no será anulado por las clases de casos derivados. Aquí está un ejemplo:

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 

De lo que se prueba:

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 
Cuestiones relacionadas