2012-04-29 10 views

Odpowiedz

74

Tylko parametry w pierwszej sekcji parametrów są uwzględniane dla równości i mieszania.

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

Aby wystawiać b jako pole:

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

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

Ale 'Foo (0) (0) .b' nie działa. Daje błąd "wartość b nie jest członkiem Foo". –

+1

+1, super! Nie wiedziałem o tym. – missingfaktor

+2

@KenBloom jeśli dodasz "val" przed "b" to zadziała: case class 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 

W razie potrzeby można zastąpić .toString.

2

można zastąpić równych i metody hasCode w klasie przypadku

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

Nie jest to bardzo atrakcyjna opcja, ponieważ [".równomierność" jest trudna do uzyskania] (http://www.artima.com/lejava/articles/equality.html) oraz '.equals' i' .hashCode' razem tworzą wiele elementów. – missingfaktor

+0

Zgadzam się, że wyrównanie równości/hashCode jest podatne na błędy (jak w java), wystarczy spojrzeć na przykładowy kod. Jednak wszystkie inne metody, zastosowanie/unapply/toString/etc będą generowane automatycznie i będą działać jak poprzednio. – andy

+0

Powiedziałbym, że łatwo się pomylić, a nie trudno to naprawić, jeśli to ma jakiś sens :) Zaktualizowałem coś bardziej poprawnego –

0

Jeśli nadpisanie toString w klasie bazowej to nie zostaną nadpisane przez wyprowadzone klasy przypadków. Oto przykład:

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 

niż ty Test:

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