2010-08-06 5 views
7
val filesHere = (new java.io.File(".")).listFiles 
val filesHere2 = (new java.io.File(".")).listFiles 

स्केला> filesHere == filesHere2
res0: बूलियन = झूठीस्काला, जावा और समानता

काफी काउंटर सहज है कि। मैं अपेक्षा करता हूं कि फाइलें यहां और फ़ाइलें हैंर 2 बराबर हैं।

यह निश्चित रूप से जावा और स्कैला के बीच एक अर्थशास्त्र विसंगति के कारण है, उदाहरण के लिए, सरणी या (फाइलें) समानता के बारे में। जाहिर है, मैं यहाँ कुछ याद कर रहा हूँ!

उत्तर

4

आप यहाँ के माध्यम से पढ़ सकते हैं:

http://ofps.oreilly.com/titles/9780596155957/AdvancedObjectOrientedProgramming.html#EqualityOfObjects

लेकिन ऐसा लगता है कि अगर आप ने क्या किया: filesHere.sameElements(filesHere2) कि यह सच होना चाहिए।

इस के लिए जावाडोक यहाँ है: http://www.scala-lang.org/api/2.6.0/scala/IterableProxy.html#sameElements%28Iterable%5BB%5D%29

अद्यतन:

पहले लिंक है कि सहायक हो सकता है के स्निपेट के एक जोड़े:

जावा, C++ में, और सी # संदर्भ के लिए == ऑपरेटर परीक्षण, मूल्य समानता नहीं है। इसके विपरीत, रूबी का == ऑपरेटर मूल्य समानता के लिए परीक्षण करता है। आप जिस भी भाषा का उपयोग कर रहे हैं, उसे याद रखना सुनिश्चित करें कि स्कैला में, == मूल्य समानता के लिए परीक्षण कर रहा है।

== काम नहीं कर के संदर्भ में सूचियाँ पर अपेक्षा के अनुरूप:

इस विसंगति की तरह लग सकता है, दो परिवर्तनशील डेटा संरचनाओं की समानता के एक स्पष्ट परीक्षण को प्रोत्साहित करने की ओर से एक रूढ़िवादी दृष्टिकोण है भाषा डिजाइनर। लंबे समय तक, यह आपको अपने सशर्त परिणामों में अप्रत्याशित परिणामों से बचा लेना चाहिए।

अद्यतन 2:

राफेल से मैं विनिर्देश को देखा, और यह दो दिन पहले हाल ही में अद्यतन के लिए दिनांकित किया गया था, और मैं http://www.scala-lang.org/files/archive/nightly/pdfs/ScalaReference.pdf में इन देख टिप्पणियों के आधार पर:

Method equals: (Any)Boolean is structural equality, where two instances 
are equal if they both belong to the case class in question and they have equal 
(with respect to equals) constructor arguments. 

class AnyRef extends Any { 
    def equals(that: Any): Boolean = this eq that 
    final def eq(that: AnyRef): Boolean = . . . // reference equality 

तो, ऐसा प्रतीत होता है कि स्केल 2.10.2 में परिभाषा नहीं बदली है, क्योंकि विनिर्देश सुसंगत प्रतीत होता है। यदि व्यवहार अलग है, तो यदि आप एक इकाई परीक्षण लिखते हैं तो इसे स्कैला के लिए एक बग के रूप में भेजा जाना चाहिए।

+0

अच्छा संसाधन, धन्यवाद! यह दिखाता है कि ऊपर उल्लिखित समस्या से निपटने के लिए कैसे (समान एलिमेंट्स का उपयोग करके, ठीक है!) लेकिन यह समझा नहीं जाता है कि समस्या (या "आश्चर्य") स्कैला> ऐरे (1, 2) == ऐरे (1) में क्यों होती है , 2) res0: बूलियन = झूठी – acherm

+0

@acherm - यही कारण है कि मैंने अद्यतन में डाल दिया, लेख के अंतिम उद्धरण को समानता के लिए स्पष्ट परीक्षण को प्रोत्साहित करने के लिए क्यों समझा जाना चाहिए। –

+0

यहां एक और दिलचस्प चर्चा: http://scalide.blogspot.com/2009/05/hashcode-equals-in-scala-28-collections.html यह स्थिति को पूरी तरह से स्पष्ट नहीं करता है, लेकिन यह दर्शाता है कि "समानता एक है दिलचस्प विषय, केवल व्याख्याओं की अविश्वसनीय सीमा के कारण इसमें हैं। " Array.scala (http://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_0_final/src//library/scala/Array.scala) पर देखकर, बराबर() विधि परिभाषित नहीं है । – acherm

8

equals() जावा सरणी की विधि किसी भी परिष्कृत की बजाय संदर्भ समानता का उपयोग करती है, और स्कैला के == बस जावा का equals() है।

+0

स्कैला == और बराबर() मूल्य समानता के लिए हैं, और eq यह है कि दो वस्तुओं के संदर्भ समानता है या नहीं। –

+1

@ जेम्स हाँ, लेकिन इस उदाहरण में बराबर() को संदर्भ समानता की जांच करने के लिए लागू किया गया है। तो इस विशेष मामले में, (स्कैला का ==) == (जावा का ==) :) –

+0

यहां एक दिलचस्प धागा है: http://scala-programming-language.1934581.n4.nabble.com/scala-Array-equality -td2001726.html लेकिन फिर भी, मैं वास्तव में उलझन में हूं। यदि स्कैला == (या "बराबर") वास्तव में जावा की बराबर() विधि (जैसा कि यह मामला लगता है) कहता है, तो यह उदाहरण समानता के बारे में स्कैला भाषा की डिजाइन पसंद को कुछ हद तक तोड़ देता है। एक स्कैला प्रोग्रामर के रूप में, मुझे जावा में समानता के अर्थशास्त्र को याद दिलाना होगा और सभी मुश्किल बिंदुओं से सावधान रहना होगा। अरे नहीं! – acherm

17

अगर मैं दुनिया पर राज किया, मैं इस आधार पर स्काला के eq विधि का बहिष्कार होता है कि नाम अत्यंत बराबरी और == साथ confusible है। इसके बजाए अंग्रेजी में एक शब्द होता है जो समानता के विपरीत पहचान व्यक्त करता है: मैं बस इसे कहूंगा है।

इसी तरह मैं स्काला के ne (जो, एक भयानक नाम है क्योंकि यह दोनों एक संक्षिप्त नाम और समझ से बाहर है) नहीं है साथ की जगह लेंगे।

मुझे लगता है कि इन्हें वास्तव में किसी भी आरईएफ में जोड़ा जा सकता है और पुरानी विधियों को इस देर के चरण में भी हटा दिया जा सकता है।

+3

मुझे यह विचार बहुत पसंद है। –

+3

हाँ, अच्छा विचार है, लेकिन "है" टाइप चेक के साथ संदिग्ध है जैसे: ओबीजे स्ट्रिंग है, जो अन्य भाषाओं में लोकप्रिय है, और इस प्रकार भ्रमित है। – tuxSlayer

8

तुलना अपेक्षित काम नहीं करती है, क्योंकि यह जावा एपीआई एक ऐरे देता है।

स्कैला के सरणी और जावा सरणी दृश्यों के पीछे समान हैं और हालांकि स्कैला की सरणी कक्षा की तरह दिखती है, यह सिर्फ एक जावा है। I.File [] (इस उदाहरण में)।

यही कारण है कि समानता की जांच को ओवरराइड नहीं किया जा सकता है। स्कैला के लिए जावा अर्थशास्त्र का उपयोग करना है।

val filesHere = (new java.io.File(".")).listFiles.toList 
val filesHere2 = (new java.io.File(".")).listFiles.toList 

यह अपेक्षा के अनुरूप काम होगा:

इस उदाहरण पर विचार।

+0

ऐरे (1, 2) == ऐरे (1, 2) या तो – FUD

+0

@FUD हाँ काम नहीं करता है, क्योंकि यह एक ऐरे है। लेकिन अगर आप 'toList'' कहते हैं - यह काम करना शुरू कर देगा। ऐसा इसलिए है क्योंकि यह स्कैला दुनिया से एक वर्ग बन जाएगा, और स्कैला में कक्षाओं को एक अच्छा 'बराबर' के साथ परिभाषित किया गया है। – VasyaNovikov