2012-04-29 10 views
32

क्या केस क्लास के बराबर/हैशोड विधि में केस क्लास के किसी क्षेत्र को अनदेखा करना संभव है?स्कैला: बराबर/हैकोड के लिए केस क्लास फ़ील्ड को अनदेखा करें?

मेरा उपयोग मामला यह है कि मेरे पास एक ऐसा क्षेत्र है जो कक्षा में शेष डेटा के लिए अनिवार्य रूप से मेटाडेटा है।

+1

आप ओवरराइट हैं hashCode/के बराबर होती है यहाँ एक उदाहरण है? –

उत्तर

74

पहले पैरामीटर अनुभाग में केवल पैरामीटर समानता और हैशिंग के लिए विचार किए जाते हैं।

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) 

अद्यतन

एक क्षेत्र के रूप b प्रदर्शित करना:

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

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

लेकिन 'फू (0) (0) .b' काम नहीं करता है। यह त्रुटि देता है 'मान बी फू का सदस्य नहीं है'। –

+1

+1, ठंडा! इसके बारे में नहीं पता था। – missingfaktor

+2

@ केनब्लूम अगर आप "बी" से पहले "वैल" जोड़ते हैं तो यह काम करेगा: केस क्लास फू (ए: इंट) (वैल बी: इंट) – 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

सहमत हैं कि बराबर/हैशकोड ओवरराइटिंग त्रुटि प्रवण है (जावा में), बस उदाहरण के लिए नमूना कोड देखता है। हालांकि अन्य सभी विधियों, लागू/अनुपयोगी/toString/आदि स्वत: जेनरेट हो जाएंगे और पहले के रूप में काम करेंगे। – 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 
संबंधित मुद्दे