2013-08-23 7 views
19

सी #/जावा दोनों में क्रमशः is की ऑपरेटर प्राथमिकता instanceof कुछ बदसूरत आवश्यक कोष्ठक की ओर ले जाती है। उदाहरण के लिए if (!bar instanceof Foo) लिखने के बजाय आपको if (!(bar instanceof Foo)) लिखना होगा।उदाहरण की प्राथमिकता के कारण/

तो भाषा टीमों ने फैसला क्यों किया कि ! में उच्च ऑपरेटर प्राथमिकता है/उदाहरण के मुकाबले? स्वीकार्य रूप से सी # में आप operator! को ओवरराइट कर सकते हैं जो कुछ परिस्थितियों में एक अलग परिणाम का कारण बनता है, लेकिन उन परिस्थितियों में बहुत दुर्लभ लगता है (और किसी भी मामले में गैर-अंतर्ज्ञानी), जबकि जांच करने का मामला कुछ प्रकार का प्रकार या उप प्रकार नहीं है और अधिक संभावित।

+0

यह [programmers.stackexchange.com] पर नहीं होना चाहिए (http://programmers.stackexchange.com/)? – Adrian

+1

@ एड्रियन इमो यह बेहतर ढंग से फिट है और मुझे प्रोग्रामर के विवरण में भाषा-सिद्धांत के बारे में कुछ भी नहीं दिख रहा है। – Voo

उत्तर

11

षड़यन्त्र सिद्धांत:

सी # डिजाइनरों आपका उपयोग नहीं करना चाहते हैं 0 ऑपरेटर। इस ऑपरेटर का उपयोग अक्सर ओओपी डिजाइन की गंध है। यदि आप इसे अक्सर इस्तेमाल करते हैं, तो शायद इसका मतलब है कि आपकी कक्षा पदानुक्रम गलत है और आपको आभासी तरीकों और पैटर्न पर अधिक भरोसा करने की आवश्यकता है। जावा डिज़ाइनर आगे भी गए: उन्होंने ऑपरेटर instanceof नाम दिया ताकि आप इसे हर बार क्रिंग कर सकें।

यह वास्तव में असंभव नहीं है। ऐसे कई मामले हैं जब भाषा और पुस्तकालय डिजाइनर कुछ विशेषताओं को उपयोग करने के लिए असुविधाजनक बनाते हैं। कुछ उदाहरण: .NET में वर्ण एन्कोडिंग (आपको हमेशा यूनिकोड का उपयोग करना चाहिए), goto पास्कल में (आपको इससे बचना चाहिए) आदि। कभी-कभी यह खराब डिज़ाइन (जैसे .NET में WPF) के कारण होता है, लेकिन कभी-कभी यह जानबूझकर होता है।

+1

यह वास्तव में वास्तव में एक अच्छा कारण है और मैं मानता हूं कि यह दूर नहीं है। जावा और सी # प्रोग्रामर को एक विशिष्ट प्रोग्रामिंग शैली की ओर धक्का देने के लिए अपने रास्ते से बाहर निकलते हैं और इस ऑपरेटर से बचने के लिए निश्चित रूप से वहां फिट बैठता है। – Voo

1

क्योंकि if (!bar instanceof Foo) लिखकर यह बार को अस्वीकार करता है और फिर उदाहरण के लिए देखता है। क्योंकि यह सबसे बाएं बयान है और मुझे नहीं लगता कि उदाहरण में भी

तो if (!(bar instanceof Foo)) यह पहले उदाहरण देता है और फिर पूरी चीज़ को अस्वीकार करता है।

अगर आप बार नकारना के लिए और फिर उदाहरण के लिए जाँच की जरूरत है तो ((!bar) instanceof Foo)

+4

हां मैं मूलभूत बातों को समझता हूं कि ऑपरेटर प्राथमिकता कैसे काम करती है। सवाल यह है कि ऑपरेटर की प्राथमिकता इस तरह से क्यों चुनी गई थी। स्पष्ट रूप से आपको 21 के बजाय 11 के सही परिणाम प्राप्त करने के लिए '5 + (2 * 3) 'लिखना नहीं है - ठीक है क्योंकि ऑपरेटर की प्राथमिकता सही ढंग से चुनी गई थी (" सही ढंग से "स्पष्ट रूप से केवल पूर्णांक के विशिष्ट डोमेन के लिए लागू होती है) । वही किया जा सकता है - या नहीं? यही तो प्रश्न है। – Voo

+0

ऑब्जेक्ट को अस्वीकार करने का क्या अर्थ है? – asteri

+0

किसी ऑब्जेक्ट को नकारना केवल तभी काम करेगा जब उसके पास एक पूर्ण रूप से जाली योग्य बूलियन मान था, मैंने सोचा होगा। – Adrian

10

यहाँ कोई आधिकारिक स्रोत के साथ इस मामले पर अपने विचार रहे हैं।

instanceof एक बहुत बड़ा ऑपरेटर है। अधिकतर ऑपरेटरों में सबसे अधिक दो अक्षर होते हैं। इसके अतिरिक्त, instanceof में इसके बीच एक चर और स्पेस होना चाहिए। इन दो अद्वितीय चीजों के कारण, जब आप !bar instanceof Foo जैसी अभिव्यक्ति को देखते हैं, तो instanceof!bar और Foo स्वाभाविक रूप से अलग दिखता है, और !bar उप-अभिव्यक्ति नहीं होने पर कई लोगों को यह आश्चर्यजनक लगेगा।

विचारों की इसी तरह की लाइनों को is पर भी लागू किया जा सकता है, जिसमें जावा ने पहले से ही क्या किया है इसके अतिरिक्त तर्क के साथ।

16

जावा में, instanceofrelational operators में से एक है और अन्य लोगों के रूप में एक ही पूर्वता है:

if (!(a instanceof b)) 
if (!(a < b)) 
:

RelationalExpression: 
    ShiftExpression 
    RelationalExpression < ShiftExpression 
    RelationalExpression > ShiftExpression 
    RelationalExpression <= ShiftExpression 
    RelationalExpression >= ShiftExpression 
    RelationalExpression instanceof ReferenceType 

उस परिप्रेक्ष्य में यह भावना है कि उन दो पंक्तियों में समान संरचना का पालन करना चाहिए बनाता से

+2

निश्चित रूप से, लेकिन यह केवल तकनीकी कारण है, यानी यह कैसे कार्यान्वित किया जाता है (और मुझे वास्तव में यह बहुत अजीब लगता है कि आप संबंधपरक ऑपरेटरों में उदाहरण डालेंगे), लेकिन क्यों नहीं उन्होंने इसे वहां रखा। – Voo

+0

RelationExpression एकमात्र श्रेणी है जो उदाहरण के लिए समझ में आता है (आईएमओ)। एक विकल्प एक विशिष्ट श्रेणी बनाने के लिए किया गया होगा। – assylias

1
  1. instanceof बहुत लंबे शब्द + या ++ जैसी बुनियादी ऑपरेटरों की तुलना में है।जब आप हालत पढ़ते हैं, तो आप कम से कम अपना ध्यान खो देते हैं।
  2. यह रिक्त स्थान से घिरा हुआ है जो पठनीयता को बढ़ा सकता है लेकिन दूसरी ओर आप को अन्य ऑपरेटरों के साथ कनेक्ट करने में असमर्थ हैं, उदा। जैसे 5+6 कर सकते हैं।

मुझे विश्वास है कि लोग कहते हैं कि करने का फैसला किया: ठीक है, कम प्राथमिकता ताकि हर कोई कोष्ठक प्रदान करनी चाहिए यकीन है कि क्या

3

हो रहा है मुझे लगता है कि यह सिर्फ ऐतिहासिक है किया जाना है। अगर मुझे जावा के पहले संस्करणों में सही ढंग से याद है तो आप बिना किसी ब्रांड्स के if(a instanceof Foo || a instanceof Bar) लिख सकते हैं। मुझे लगता है कि जावा 2 के आसपास एक बदलाव आया था। मुझे नहीं पता कि उन्होंने इसे उच्च प्राथमिकता क्यों नहीं दिया (उदा। लॉजिकल से अधिक नहीं)। शायद क्योंकि यह टाइपकास्ट ऑपरेटर में हस्तक्षेप करेगा और इस प्रकार संगतता तोड़ देगा?

सी # ने जावा के समान ही वही प्राथमिकता का उपयोग किया है।

मुझे अभी भी लगता है कि यह गलती और/या तार्किक और/या समान स्तर पर समान स्तर पर रखने के लिए एक गलती है। if((x&(FLAG1|FLAG2)) != 0) … जैसी चीजें लिखने के लिए परेशान करना है।

1

obiously, !b instanceof SomeType (पढ़ें: "b नकारना, तो अगर परिणामस्वरूप मूल्य प्रकार SomeType की है जाँच") की तरह एक अभिव्यक्ति जावा में ज्यादा मतलब नहीं है:

तार्किक रूप से, b किसी तरह का होना ही था बूलियन ऑब्जेक्ट (ताकि ! काम करता है) और यहां तक ​​कि यदि आपने इसके मूल्य को अस्वीकार कर दिया है, तो यह अभी भी एक ही प्रकार का बुलियन वैल्यू होगा, तो इसे पहले स्थान पर क्यों नकार दें?

(असल में, आप भी यह नहीं कर सकते: b एक boolean नहीं किया जा सकता, क्योंकि instanceof इसे फिर से की आवश्यकता है एक असली Object होने के लिए है, लेकिन फिर, अगर b एक Boolean है, !b अभी भी एक आदिम करने के लिए मूल्यांकन करेगा boolean, इसलिए instanceof काम नहीं करता है।)

इसलिए हम कह सकते हैं कि !b instanceof SomeType जावा में कोई अर्थपूर्ण अर्थ नहीं है। तो हम इसका अर्थ फिर से सौंप सकते हैं "जांचें कि bSomeType प्रकार का नहीं है" - क्या हम नहीं कर सकते?

यह देखते हुए कि इस अर्थ की दृष्टि से बदल दिया गया है सकते हैं और अभी भी नहीं किया गया था मुझे निष्कर्ष यह है कि यह वास्तव में जानबूझकर नहीं था, लेकिन एक और अधिक व्यावहारिक instanceof के लिए कम पूर्वता के साथ जाने के वजह नहीं थी साथ छोड़ देता है:

मेरे सिर के ऊपर से, मुझे संदेह होगा कि अगर आप instanceof यूनरी ऑपरेटर ! की तुलना में उच्च प्राथमिकता देते हैं तो पार्सिंग जटिल हो जाती है। आप इसे देखना चाहेंगे।

दूसरी ओर, यदि !b instanceof SomeType मतलब होगा "जाँच करता है, तो b प्रकार SomeType की नहीं है", यह अभी भी यह सोच कर कि !b पर चल रही है जबकि वास्तव में इस instanceof का परिणाम नकारता में नौसिखिया प्रोग्रामर धोखा हो सकता है, तो यह कम है !b instanceof SomeType छोड़ने के लिए अस्पष्ट अनिवार्य रूप से अपरिभाषित।

1

instanceof एक बाइनरी ऑपरेटर है। ! एक यूनरी ऑपरेटर है।

यह बहुत भ्रमित ! की तुलना में अधिक मजबूती से बाध्य करने के लिएinstanceof के लिए किया जाएगा।
भ्रम का एक उत्कृष्ट उदाहरण ** और अजगर, जहां हमारे पास में - है:

-1 ** 2 == -(1 ** 2) # true 

मैं तुम्हारे बारे में पता नहीं है, लेकिन यह सिर्फ अजगर में मेरे लिए हास्यास्पद लग रहा है, इसलिए मैं खुश हूँ कि वे जावा में एक ही चीज़ नहीं कर रहे हैं।

एक और अजगर उदाहरण है:

False is (not None) # false 

और

False is not None  # true 

जो मुझे लगता है कि समान रूप से भ्रामक है, इस बार क्योंकि is और is not विभिन्न ऑपरेटरों रहे हैं।

0

क्योंकि सी प्रोग्रामिंग भाषा गलत समझ में आ गया है, और जावा आँख बंद करके सी

पीछा सी में! और ~ वही प्राथमिकता है। यह वास्तव में अभ्यास में सी में ज्यादा मायने रखता नहीं है क्योंकि < बी के बजाय लिखता है! (> = b)।

लेकिन ऑपरेटर को कोई अधिसूचना नहीं है।

आप यह भी पूछ सकते हैं कि क्यों/*/* */*/ठीक से घोंसला नहीं है। या क्यों जावा 0 से गिना जाता है या फिर एक शून्य कीवर्ड क्यों होना चाहिए। या क्यों जावा endif (या fi) के बजाय भयभीत {{} {}} नोटेशन का उपयोग करता है। यह सभी सी विरासत है।

और शायद अच्छे कारण के लिए। सी प्रोग्रामर तर्क देंगे कि ये सभी चीजें सही दृष्टिकोण हैं, क्योंकि यही वह है जिसका उपयोग वे करते हैं। और जावा की पहली नौकरी को ध्यान में रखना और इस्तेमाल किया जाना था, कई अन्य छोटी भूल गई प्रोग्रामिंग भाषाओं के विपरीत।

आभारी रहें कि जावा में शून्य समाप्त नहीं हुआ है।

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