2010-09-17 12 views
22

Programming in Scala में लेखकों ने लिखा है कि स्कैला का == फ़ंक्शन संदर्भ समानता के बजाय मूल्य समानता की तुलना करता है।ऐरे के लिए ऐरे का == फ़ंक्शन क्यों सही नहीं है (1,2) == ऐरे (1,2)?

इस सूची में अपेक्षा के अनुरूप काम करता है:

scala> List(1,2) == List(1,2) 
res0: Boolean = true 

हालांकि यह सरणियों पर काम नहीं करता:

scala> Array(1,2).sameElements(Array(1,2)) 
res2: Boolean = true 
:

scala> Array(1,2) == Array(1,2) 
res1: Boolean = false 

लेखकों बजाय sameElements फ़ंक्शन का उपयोग करने की सलाह देते

एक स्पष्टीकरण के रूप में वे लिखते हैं:

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

  1. इसका क्या मतलब है? किस तरह के अप्रत्याशित परिणाम क्या वे बात कर रहे हैं? अगर सरणी में एक ही स्थिति में समान तत्व होते हैं तो मैं वापस लौटने की तुलना में सरणी तुलना से और क्या उम्मीद कर सकता हूं? बराबर काम List पर काम क्यों करता है लेकिन Array पर नहीं?

  2. मैं बराबर कार्यों को सरणी पर कैसे काम कर सकता हूं?

+0

मैंने इस पुस्तक में भी इस स्पष्टीकरण को नोट किया है। यह सही नहीं है, नीचे अपना जवाब देखें। इस त्रुटि के अलावा, पुस्तक बहुत अच्छी है। –

+0

कोई संक्षेप में बता सकता है कि क्या हो रहा है, "जावा संदर्भ समानता के रूप में सरणी पर मूल्य समानता को परिभाषित करता है, तत्व-दर-तत्व समानता नहीं।" –

+0

संभावित डुप्लिकेट [ऐरे प्रकार के अजीब व्यवहार] (http://stackoverflow.com/questions/3213368/strange-behaviour-of-the-array-type) – Suma

उत्तर

26

यह सच है कि पुस्तक में दी गई स्पष्टीकरण संदिग्ध है, लेकिन उचित होने के लिए यह लिखा गया था जब यह अधिक विश्वासयोग्य था। यह अभी भी 2.8 में सच है, लेकिन हमें अलग-अलग तर्कों को फिर से निकालना होगा क्योंकि जैसा आपने देखा है, अन्य सभी संग्रह तत्व तुलना करते हैं भले ही वे उत्परिवर्तनीय हों।

Arrays को संग्रह के बाकी हिस्सों की तरह लगने की कोशिश कर रहा था, लेकिन यह एक बहुत ही कमजोर अमूर्त था और अंत में यह असंभव था। यह निर्धारित किया गया था, सही ढंग से मुझे लगता है कि, हमें अन्य चरम पर जाना चाहिए और मूल क्षमताओं को अपनी क्षमताओं को बढ़ाने के लिए अंतर्निहित मशीनरी का उपयोग करके, जिस तरह से वे हैं, आपूर्ति करते हैं। जहां यह सबसे अधिक ध्यान देने योग्य है, तो स्ट्रिंग और बराबर है, क्योंकि उनमें से कोई भी Arrays पर उचित फैशन में व्यवहार नहीं करता है, लेकिन हम उन कॉलों को अंतर्निहित रूपांतरणों से रोक नहीं सकते क्योंकि उन्हें java.lang.Object पर परिभाषित किया गया है। (रूपांतरण केवल तब होता है जब कोई अभिव्यक्ति चेक टाइप नहीं करती है, और वे हमेशा चेक टाइप करते हैं।)

तो आप अपनी स्पष्टीकरण चुन सकते हैं, लेकिन अंत में सरणी मूलभूत रूप से अंतर्निहित वास्तुकला से अलग तरीके से व्यवहार की जाती है और कीमत पर भुगतान किए बिना उस पर पेपर का कोई तरीका नहीं है। यह एक भयानक स्थिति नहीं है, लेकिन ऐसा कुछ है जिसे आपको अवगत होना है।

+0

तो आप कह रहे हैं कि भाषा डिजाइनर यह नहीं सोचते कि यह असंगतता काफी अच्छी डिजाइन है, बल्कि इसे कम से कम दर्दनाक समझौता के रूप में देखते हैं? –

+6

खुद के लिए बोलते हुए, प्रोग्रामिंग कम है लेकिन "कम से कम दर्दनाक समझौता" नहीं है कि यह मुझे इसका आनंद लेने से रोकता है। और बाकी दुनिया के लिए बोलते हुए, मैं कहूंगा कि आपका पैराफ्रेज एक उचित सारांश है। – extempore

-3

यह सभी संदर्भित पारदर्शिता के बारे में है। विचार यह है कि, यदि दो मान == हैं, तो इससे कोई फर्क नहीं पड़ता कि आप किस चीज के लिए उपयोग करते हैं। यदि आपके पास एक ही सामग्री के साथ दो सरणी हैं, तो यह स्पष्ट रूप से महत्वपूर्ण है कि आप किस को संशोधित करते हैं, इसलिए == झूठी रिटर्न देता है जब तक वे समान एक नहीं होते हैं।

+0

यह सही नहीं है! ऐरे को छोड़कर सभी संग्रहों के लिए स्कैला लागू ==। मेरा अपना जवाब देखें। –

+0

मैंने सोचा कि मैं स्केल –

+0

में संदर्भों की तुलना करने के लिए 'eq' फ़ंक्शन का उपयोग करूंगा, ठीक है, हाँ। ऐसा करने के लिए eq विधि का प्रयोग करें। लेकिन याद रखें कि जब आप कक्षा बनाते हैं, (केस श्रेणी नहीं), तो == संदर्भों की तुलना करेंगे यदि आप बराबर ओवरराइड नहीं करते हैं()। –

7

यह सटीक प्रश्न कई बार आवाज उठाया गया है (स्वयं भी, Strange behaviour of the Array type देखें)।

ध्यान दें कि यह केवल Array संग्रह है जो == का समर्थन नहीं करता है, अन्य सभी संग्रह करते हैं। मूल कारण यह है कि Array जावा array है।

+0

भाषा डिजाइनर जावा 'सरणी' को 'ऐरेसेक' या 'लपेटा हुआ' के बजाय डिफ़ॉल्ट 'ऐरे' क्यों चुनते हैं जो अपेक्षित व्यवहार करेगा? –

+1

@Stefan - क्योंकि दूसरों को आदिम प्रकारों को बॉक्स करना होता है, और इस प्रकार तेज़ नहीं चलते हैं - जो ठीक है जब आप किसी सरणी का उपयोग करना चाहते हैं। साथ ही, जावा कोड का उपयोग करते समय, जो कई करते हैं, सरणी बहुत अधिक होती है। इस प्रकार बुराइयों में से कम 'ऐरे' जावा सरणी बनाना है; लागत यह है कि '==' असंगत व्यवहार करता है। इसके अलावा, अन्यथा 'ऐरे' के लिए कोई स्पष्ट विकल्प नहीं है। क्या यह 'ArraySeq' होना चाहिए? 'ArrayBuffer' के बारे में कैसे? शायद 'लपेटा हुआ ऐरे'? उनमें से प्रत्येक के पास मौजूदा के लिए सभ्य कारण हैं, लेकिन कोई भी स्पष्ट रूप से स्पष्ट उम्मीदवार नहीं है। –

+0

तो आप कह रहे हैं ए) यह एक प्रदर्शन विकल्प था बी) मैं सामान्य रूप से स्कैला में सरणी का उपयोग नहीं करना चाहिए, इसलिए इससे कोई फर्क नहीं पड़ता कि उनके 'बराबर' कार्य असंगत है? –

संबंधित मुद्दे