मैं इस समाधान के साथ आया जो सभी क्षेत्रों के माध्यम से और निजी क्षेत्रों के लिए, स्काला में एक इसी विधि को पाता है। दरअसल, केस क्लास के पास एक ही नाम के तरीकों के माध्यम से निजी सदस्य सुलभ होते हैं।
implicit class ReallyEqual[T](a: T) {
import java.lang.reflect.Modifier._
def ==:==[U](b: U): Boolean = {
val fieldsA = a.getClass.getDeclaredFields
val methodsA = a.getClass.getDeclaredMethods
val mapA = (methodsA.toList map (z => (z.getName(), z))).toMap
val fieldsB = b.getClass.getDeclaredFields
val methodsB = b.getClass.getDeclaredMethods
val mapB = (methodsB.toList map (z => (z.getName(), z))).toMap
fieldsA.length == fieldsB.length &&
(true /: (fieldsA zip fieldsB)){ case (res, (aa, bb)) =>
if(((aa.getModifiers & STATIC) != 0) || ((bb.getModifiers & STATIC) != 0)) { res // ignore
} else if(((aa.getModifiers & (PRIVATE | PROTECTED)) == 0) && ((bb.getModifiers & (PRIVATE | PROTECTED)) == 0)) {
res && aa == bb && aa.get(a) ==:== bb.get(b)
} else if((mapA contains aa.getName) && (mapB contains bb.getName)) {
res && mapA(aa.getName).invoke(a) == mapB(aa.getName).invoke(b)
} else res
}
}
}
trait EqualBad {
override def equals(other: Any) = false
}
case class MyCaseClass(x: Int, y: List[Int]) extends EqualBad
MyCaseClass(1, List(1, 2)) ==:== MyCaseClass(1, List(1, 2)) // true
MyCaseClass(1, List(1, 2)) ==:== MyCaseClass(1, List(2, 2)) // false
MyCaseClass(1, List(1, 2)) ==:== MyCaseClass(2, List(1, 2)) // false
MyCaseClass(1, List(1, 2)) == MyCaseClass(1, List(1, 2)) // false
तुम भी विधि में पिछले == बदलकर इसे और अधिक पुनरावर्ती कर सकते हैं ReallyEqual
को ==: ==
सावधान: यह पूर्णांकों के लिए काम नहीं करेगा, क्योंकि इंट नहीं है कोई क्षेत्र या विधियां। पूर्व: 1 ==: == 2 सत्य वापस आ जाएगा।
स्रोत
2013-10-14 13:11:27
केस कक्षाओं की वस्तुओं में आप 'productIterator.toList' का उपयोग कर सकते हैं यदि आप केवल श्रेणी मूल्यों में रुचि रखते हैं। – pedrofurla
productIterator.toList काम नहीं किया। यह सिर्फ एक सूची में उदाहरण डाल दिया। – ttt
दोनों ऑब्जेक्ट्स को प्रतिबिंबित करें और अपने फ़ील्ड और मानों की तुलना करें। – Ashalynd