2012-04-29 13 views

答えて

74

第1パラメータセクションのパラメータのみが等価とハッシュとみなされます。

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

しかし 'Foo(0)(0).b'は動作しません。 '値bはFooのメンバーではありません。 'というエラーを返します。 –

+1

+1、クール!これについて知りませんでした。 – missingfaktor

+2

@KenBloom "b"の前に "val"を追加すると、動作します: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 

必要に応じて、.toStringを上書きすることができます。

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

['.equals'は右に出にくいので、 http://www.artima.com/lejava/articles/equality.html)、 '.equals'と' .hashCode'は一緒に多くの定型文を作成します。 – missingfaktor

+0

は、equal/hashCodeの上書きがエラーが起こりやすい(javaと同様)ことに同意します。例のサンプルコードを参照するだけです。ただし、他のすべてのメソッドapply/unapply/toString/etcは自動的に生成され、前と同じように動作します。 – andy

+0

私はそれが意味をなさないならば、正しくなるのは難しいのではなく、間違ってしまうのは簡単だと思います:) –

0

で等号とhasCodeメソッドをオーバーライドすることができますベースクラスのそれに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 
関連する問題