अपवादों को फेंकते समय अशक्त संदर्भों को क्यों ठीक माना जाता है?


21

मुझे कुछ प्रोग्रामिंग लैंग्वेज लोगों द्वारा अशक्त संदर्भों के लगातार कोसने की समझ नहीं है। उनके बारे में इतना बुरा क्या है? अगर मैं एक ऐसी फ़ाइल का उपयोग करने का अनुरोध करता हूं जो मौजूद नहीं है तो मैं एक अपवाद या अशक्त संदर्भ प्राप्त करने के लिए पूरी तरह से खुश हूं और अभी तक अपवादों को अच्छा माना जाता है लेकिन अशक्त संदर्भों को बुरा माना जाता है। इसके पीछे क्या तर्क है?



2
कुछ भाषाएं दूसरों की तुलना में बेहतर तरीके से दुर्घटनाग्रस्त हो जाती हैं। एक "प्रबंधित कोड" के लिए, जैसे कि .Net / Java एक अशक्त रेफरी एक अन्य प्रकार की समस्या है, जबकि अन्य मूल कोड इसे इनायत से संभाल नहीं सकते हैं (आपने किसी विशिष्ट भाषा का उल्लेख नहीं किया है)। एक प्रबंधित दुनिया में भी, कभी-कभी आप असफल-सुरक्षित कोड (एम्बेडेड ?, हथियार?) लिखना चाहते हैं, और कभी-कभी आप जोर से ASAP (इकाई परीक्षण) को कुतिया बनाना चाहते हैं। दोनों प्रकार के कोड को एक ही लाइब्रेरी में कॉल किया जा सकता है - जो एक समस्या होगी। सामान्य तौर पर मुझे लगता है कि कोड जो कंप्यूटर की भावनाओं को चोट नहीं पहुंचाने की कोशिश करता है वह एक बुरा विचार है। विफल-सुरक्षा वैसे भी HARD है।
नौकरी

@ जोब: यह आलस्य की वकालत कर रहा है। यदि आप जानते हैं कि एक अपवाद को कैसे संभालना है, तो आप इसे संभालते हैं। कभी-कभी उस हैंडलिंग में एक और अपवाद फेंकना शामिल हो सकता है, लेकिन आपको कभी भी एक अशक्त संदर्भ अपवाद को बेकार नहीं जाने देना चाहिए । कभी। यह हर रखरखाव प्रोग्रामर का बुरा सपना है; यह पूरे पेड़ में सबसे बेकार अपवाद है। बस स्टैक ओवरफ्लो पूछें
Aaronaught

या इसे दूसरे तरीके से रखने के लिए - त्रुटि जानकारी का प्रतिनिधित्व करने के लिए किसी प्रकार का कोड क्यों नहीं लौटाया जाए। यह तर्क आने वाले वर्षों के लिए रोष होगा।
gbjbaanb

जवाबों:


24

अशक्त संदर्भों को अपवादों की तुलना में किसी भी अधिक "दूर नहीं" किया जाता है, कम से कम किसी के द्वारा जो मैंने कभी भी जाना या पढ़ा है। मुझे लगता है कि आप पारंपरिक ज्ञान को गलत समझ रहे हैं।

क्या बुरा है एक अशक्त संदर्भ (या एक अशक्त सूचक को निष्क्रिय करने) का उपयोग करने का प्रयास है । यह बुरा है क्योंकि यह हमेशा एक बग इंगित करता है; आप उद्देश्य पर ऐसा कुछ कभी नहीं करेंगे, और यदि आप इसे उद्देश्य पर कर रहे हैं, तो यह और भी बुरा है, क्योंकि यह असंभव व्यवहार को बगिया व्यवहार से अलग करना असंभव बना रहा है।

वहाँ कुछ फ्रिंज समूह हैं, जो वास्तव में किसी कारण के लिए अशक्तता की अवधारणा से घृणा करते हैं, लेकिन जैसा कि एड बताते हैं , अगर आपके पास नहीं है nullया nilफिर आपको बस इसे किसी और चीज़ से बदलना होगा, जिससे कुछ हो सकता है एक दुर्घटना (जैसे डेटा भ्रष्टाचार) से भी बदतर।

कई ढांचे, वास्तव में, दोनों अवधारणाओं को गले लगाते हैं; उदाहरण के लिए, .NET में, एक बार-बार आपको जो पैटर्न दिखाई देगा, वह एक तरीका है, एक शब्द से उपसर्ग Try(जैसे TryGetValue)। में Tryमामले, संदर्भ को उसके डिफ़ॉल्ट मान (आमतौर पर करने के लिए सेट कर दिया जाता nullहै), और अन्य मामले में, एक अपवाद फेंक दिया है। दृष्टिकोण के साथ कुछ भी गलत नहीं है; दोनों अक्सर उन वातावरणों में उपयोग किए जाते हैं जो उनका समर्थन करते हैं।

यह वास्तव में सभी शब्दार्थों पर निर्भर करता है। यदि nullएक वैध वापसी मूल्य है, जैसा कि संग्रह की खोज के सामान्य मामले में है, तो वापस लौटें null। दूसरी ओर, अगर यह होता है नहीं एक वैध वापसी मान - उदाहरण के लिए, एक रिकार्ड एक प्राथमिक कुंजी है कि अपने डेटाबेस से आया है का उपयोग कर के लिए देख - तो लौट रहा nullएक बुरा विचार होगा क्योंकि फोन करने वाले यह उम्मीद नहीं की जाएगी और शायद इसके लिए जाँच नहीं करेगा।

यह पता लगाना बहुत आसान है कि किस शब्दार्थ का उपयोग करना है: क्या किसी फ़ंक्शन के परिणाम के अपरिभाषित होने का कोई मतलब है? यदि हां, तो आप एक अशक्त संदर्भ वापस कर सकते हैं। यदि नहीं, तो एक अपवाद फेंकें।


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

3
@ ErikKronberg, हां, "बिलियन डॉलर की गलती" और यह सब बकवास है, लोगों की परेड इसे बाहर करने और इसे ताजा और आकर्षक होने का दावा करने वाली कभी खत्म नहीं होती, यही कारण है कि पिछले टिप्पणी धागा हटा दिया गया था। ये क्रांतिकारी प्रतिस्थापन लोग कभी भी ऊपर लाने में असफल नहीं होते हैं, हमेशा अशक्त वस्तु, विकल्प या अनुबंध के कुछ प्रकार होते हैं, जो वास्तव में जादुई रूप से अंतर्निहित तर्क त्रुटि को समाप्त नहीं करते हैं, वे क्रमशः इसे स्थगित या बढ़ावा देते हैं। वैसे भी, इस जाहिर भाषाओं जो प्रोग्रामिंग के बारे में एक सवाल है ऐसा है null, तो वास्तव में, हास्केल यहाँ बहुत अप्रासंगिक है।
आरोनियट

1
क्या आप गंभीरता से तर्क दे रहे हैं कि अशक्त के लिए परीक्षण की आवश्यकता नहीं है, यह आवश्यक है?
जोहाना लार्सन

3
@ एरिक क्रोनबर्ग: हां, मैं "गंभीरता से बहस कर रहा हूं" कि अशक्त के लिए परीक्षण करना विशेष रूप से अलग नहीं है (ए) एक अशक्त वस्तु के व्यवहार के आसपास एक आवेदन के प्रत्येक स्तरीय को डिजाइन करने के लिए, (बी) पैटर्न-मैच के लिए होने से विकल्प हर समय, या (ग) कैली को "मैं नहीं जानता" कहने की अनुमति नहीं देता और अपवाद या दुर्घटना को मजबूर करता हूं। वहाँ एक कारण है कि nullइतने लंबे समय के लिए इतनी अच्छी तरह से सहन किया है, और जो लोग कहते हैं, अन्यथा अधूरा आवश्यकताओं या अंततः स्थिरता जैसी बाधाओं के साथ वास्तविक दुनिया एप्लिकेशन को डिजाइन करने वाले बहुत कम अनुभव वाले शिक्षाविदों लगते हैं।
हारून

3
@ चेतावनी: कभी-कभी मैं चाहता हूं कि टिप्पणियों के लिए एक डाउनवोट बटन था। उस तरह शेख़ी करने का कोई कारण नहीं है।
माइकल शॉ

11

बड़ा अंतर यह है कि यदि आप NULLs को संभालने के लिए कोड छोड़ देते हैं, तो आपका कोड कुछ असंबंधित त्रुटि संदेश के साथ बाद के चरण में संभवतः दुर्घटनाग्रस्त होता रहेगा, जहां अपवादों के साथ, विफलता के प्रारंभिक बिंदु पर अपवाद को उठाया जाएगा (खोलना आपके उदाहरण में पढ़ने के लिए एक फ़ाइल)।


4
NULL को संभालने में विफलता आपके कोड के बीच इंटरफ़ेस की विलक्षण अज्ञानता होगी और जो कुछ भी इसे वापस कर देगा। जो डेवलपर्स उस गलती को करते हैं वे दूसरों को एक ऐसी भाषा में बनाते हैं जो NULLs नहीं करती है।
ब्लरफेल

@ बेलर, आदर्श तरीके काफी कम हैं, और इस प्रकार यह पता लगाना आसान है कि समस्या कहां हो रही है। एक अच्छा डीबगर आमतौर पर एक शून्य संदर्भ अपवाद को अच्छी तरह से शिकार कर सकता है, भले ही कोड लंबा हो। यदि मैं रजिस्ट्री से महत्वपूर्ण सेटिंग पढ़ने की कोशिश कर रहा हूं, तो मुझे क्या करना चाहिए? मेरी रजिस्ट्री में गड़बड़ी हुई है और मैं उपयोगकर्ता को विफल करने और परेशान करने से बेहतर हूं, चुपचाप एक नोड को फिर से बनाने और इसे डिफ़ॉल्ट रूप से सेट करने के लिए। यदि कोई वायरस ऐसा करता है तो क्या होगा? तो, अगर मुझे एक अशक्त मिलता है, तो क्या मुझे एक विशेष अपवाद फेंकना चाहिए या बस इसे चीर देना चाहिए? छोटे तरीकों के साथ क्या बड़ा अंतर है?
जॉब

@ जोब: यदि आपके पास डिबगर नहीं है तो क्या होगा? आपको लगता है कि आपके आवेदन का 99.99% उस समय रिलीज के माहौल में चलने वाला है? जब ऐसा होता है, तो आप चाहते हैं कि आप अधिक सार्थक अपवाद का उपयोग करें। आपके ऐप को अभी भी उपयोगकर्ता को विफल और परेशान करना पड़ सकता है, लेकिन कम से कम यह डिबग जानकारी को आउटपुट करेगा जो आपको समस्या को तुरंत ट्रैक करने में सक्षम करेगा , इस प्रकार न्यूनतम को झुंझलाहट कहा जाएगा।
Aaronaught

@Birfl, कभी-कभी मैं उस मामले को संभालना नहीं चाहता जहाँ एक अशक्त वापसी स्वाभाविक होगी। उदाहरण के लिए, मान लें कि मेरे पास मानों के लिए एक कंटेनर मैपिंग कुंजी है। यदि मेरा तर्क यह गारंटी देता है कि मैंने कभी उन मूल्यों को पढ़ने का प्रयास नहीं किया है जिन्हें मैंने पहले स्टोर नहीं किया था, तो मुझे कभी भी निराश नहीं होना चाहिए। उस स्थिति में, मेरे पास बहुत कुछ अपवाद होगा जो यह बताने के लिए जितना संभव हो सके उतनी जानकारी प्रदान करता है, जो गलत हो गया, बल्कि फिर प्रोग्राम में रहस्यमयी रूप से कहीं और विफल होने के लिए एक अशक्त वापसी।
विंस्टन एवर्ट

इसे दूसरे तरीके से रखने के लिए, अपवादों के साथ मुझे स्पष्ट रूप से असामान्य मामले को संभालना होगा अन्यथा मेरा कार्यक्रम तुरंत समाप्त हो जाता है। अशक्त संदर्भों के साथ यदि कोड स्पष्ट रूप से असामान्य मामले को नहीं संभालता है, तो यह सीमित करने की कोशिश करेगा। मुझे लगता है कि अब फेल होने के मामले को लेना बेहतर है।
विंस्टन एवर्ट

8

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

इसके अलावा, यह नल के साथ सबसे आम मुद्दा नहीं है। अधिकांश लोग एक फ़ंक्शन को कॉल करने के बाद नल की जांच करना याद करते हैं जो इसे वापस कर सकते हैं। समस्या आपके प्रोग्राम के निष्पादन में विभिन्न बिंदुओं पर चर को शून्य होने की अनुमति देकर आपके स्वयं के डिज़ाइन में कहीं अधिक फसल देती है। आप अपने कोड को इस तरह से डिज़ाइन कर सकते हैं कि अशक्त मानों को कभी अनुमति नहीं दी जाती है, लेकिन यदि भाषा के स्तर पर शून्य की अनुमति नहीं थी, तो इसमें से कोई भी आवश्यक नहीं होगा।

हालाँकि, व्यवहार में आपको यह संकेत देने के लिए अभी भी किसी तरह की आवश्यकता होगी कि क्या एक चर है या आरंभिक नहीं है। फिर आपके पास बग का एक रूप होगा, जिसमें आपका प्रोग्राम क्रैश नहीं होता है, लेकिन इसके बजाय संभवतः कुछ अमान्य, डिफ़ॉल्ट मान का उपयोग करना जारी रखता है। मैं ईमानदारी से नहीं जानता कि कौन सा बेहतर है। अपने पैसे के लिए मुझे जल्दी और अक्सर दुर्घटना करना पसंद है।


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

3
@ जामे बाल्टर: मुझे लगता है कि मैं इस उलझन में हूँ कि यह वास्तव में अभ्यास में कैसे मदद करेगा। किसी भी गैर-तुच्छ कार्यक्रम में आपको कुछ बिंदुओं पर उन मूल्यों के साथ सौदा करना होगा जो कि आरंभिक नहीं हो सकते हैं। तो, डिफ़ॉल्ट मान को दर्शाने का कोई तरीका होना चाहिए। जैसे, आपको अभी भी जाने से पहले इसके लिए जांच करनी होगी। इसलिए, संभावित दुर्घटना के बजाय, अब आप संभावित रूप से अमान्य डेटा के साथ काम कर रहे हैं।
एड एस।

1
आपको यह भी पता है कि जब आपको nullरिटर्न वैल्यू मिलती है तो क्या होता है : आपके द्वारा मांगी गई जानकारी मौजूद नहीं है। कोई अंतर नहीं है। किसी भी तरह से, कॉल करने वाले को रिटर्न वैल्यू को मान्य करना होगा यदि उसे वास्तव में किसी विशेष उद्देश्य के लिए उस जानकारी का उपयोग करने की आवश्यकता है। चाहे वह मान्य null, शून्य वस्तु या मानद हो, कोई व्यावहारिक अंतर नहीं है।
Aaronaught

1
@ जैम बैटर: ठीक है, मैं अभी भी व्यावहारिक अंतर नहीं देखता हूं, और मैं यह नहीं देखता कि अकादमिक क्षेत्र के बाहर वास्तविक कार्यक्रमों को लिखने वाले लोगों के लिए जीवन कैसे आसान हो जाता है। इसका मतलब यह नहीं है कि वहाँ लाभ नहीं हैं, बस वे मुझे स्पष्ट नहीं लगते हैं।
एड एस

1
मैंने दो बार एक Uninitialized वर्ग के साथ व्यावहारिक अंतर को समझाया है - यह अशक्त वस्तु की उत्पत्ति की पहचान करता है - यह संभव है कि जब बग की अशांति हो तो बग को इंगित करना संभव हो। अशक्त-कम प्रतिमानों के आसपास डिज़ाइन की जाने वाली भाषाओं के लिए, वे समस्या को गेट-गो से बचाते हैं - वे प्रोग्राम के वैकल्पिक तरीके प्रदान करते हैं। असिंचित चर से बचें; अगर आप उनसे परिचित नहीं हैं, तो समझ पाना मुश्किल हो सकता है। संरचित प्रोग्रामिंग, जो कीड़ों के एक बड़े वर्ग से भी बचती है, को एक बार "अकादमिक" भी माना जाता था।
जिम बेल्टर 24:11

5

टोनी होरे, जिन्होंने पहली बार में एक अशक्त संदर्भ का विचार बनाया, इसे अपनी एक मिलियन डॉलर की गलती कहते हैं

समस्या अशक्त संदर्भों के बारे में नहीं है, बल्कि अधिकांश (अन्यथा) प्रकार की सुरक्षित भाषाओं में उचित प्रकार की जाँच के अभाव के बारे में है।

भाषा से समर्थन की इस कमी का मतलब है कि कीड़े "अशक्त-बग" का पता लगने से पहले लंबे समय तक कार्यक्रम में गुप्त हो सकता है। इस तरह की कीड़े की प्रकृति, निश्चित रूप से है, लेकिन "नल-कीड़े" अब परिहार्य होने के लिए जाने जाते हैं।

यह समस्या विशेष रूप से C या C ++ (उदाहरण के लिए) में मौजूद है, क्योंकि यह "हार्ड" त्रुटि के कारण होता है (यह प्रोग्राम का एक क्रैश, तत्काल, कोई सुंदर पुनर्प्राप्ति के साथ नहीं)।

अन्य भाषाओं में, हमेशा सवाल है कि उन्हें कैसे संभालना है।

जावा या सी # में आपको एक अपवाद मिलेगा यदि आप अशक्त संदर्भ पर एक विधि को लागू करने का प्रयास करते हैं, और यह ठीक हो सकता है। और इसलिए अधिकांश Java या C # प्रोग्रामर्स को इसके लिए उपयोग किया जाता है और समझ में नहीं आता है कि कोई व्यक्ति अन्यथा क्यों करना चाहता है (और C ++ पर हंसता है)।

हास्केल में, आपको स्पष्ट रूप से अशक्त मामले के लिए एक कार्रवाई प्रदान करनी होगी, और इसलिए हास्केल प्रोग्रामर अपने सहयोगियों पर उदास हैं, क्योंकि उन्हें यह सही (सही?) मिला है।

यह वास्तव में, पुरानी त्रुटि-कोड / अपवाद बहस है, लेकिन इस बार त्रुटि-कोड के बदले में एक प्रहरी मूल्य के साथ ।

जैसा कि हमेशा जो भी सबसे उपयुक्त होता है वह वास्तव में उस स्थिति और आपके द्वारा खोजे जा रहे शब्दार्थ पर निर्भर करता है।


ठीक। nullवास्तव में बुराई है, क्योंकि यह प्रकार की प्रणाली को नष्ट कर देता है । (दी गई, विकल्प में कम से कम कुछ भाषाओं में इसकी वाचालता में एक खामी है।)
मैकेनिकल घोंघा

2

आप एक अशक्त सूचक के लिए एक मानव पठनीय त्रुटि संदेश संलग्न नहीं कर सकते।

(हालांकि, आप लॉग फ़ाइल में एक त्रुटि संदेश छोड़ सकते हैं।)

कुछ भाषाओं / वातावरणों में जो सूचक अंकगणित की अनुमति देते हैं, यदि सूचक तर्क में से एक शून्य है और इसे गणना में अनुमति दी जाती है, तो परिणाम एक अमान्य , गैर-शून्य सूचक होगा। (*) आप को अधिक शक्ति।

(*) यह COM प्रोग्रामिंग में बहुत कुछ होता है , जहाँ यदि आप एक इंटरफ़ेस मेथड में कॉल करने का प्रयास करते हैं, लेकिन इंटरफ़ेस पॉइंटर अशक्त है, तो इसका परिणाम अमान्य पते पर कॉल होगा जो लगभग शून्य है, लेकिन बिल्कुल नहीं।


2

तकनीकी रूप से और वैचारिक रूप से किसी त्रुटि को इंगित करने के लिए NULL (या संख्यात्मक शून्य, या बूलियन असत्य) लौटना गलत है।

तकनीकी रूप से, आप प्रोग्रामर पर वापस लौटने के मूल्य की तुरंत जाँच कर रहे हैं , ठीक उसी बिंदु पर जहाँ वह लौटा है। यदि आप एक पंक्ति में बीस फाइलें खोलते हैं, और NULL को वापस करके त्रुटि सिग्नलिंग की जाती है, तो उपभोग कोड को प्रत्येक फ़ाइल को व्यक्तिगत रूप से पढ़ा जाना चाहिए, और किसी भी लूप और इसी तरह के निर्माण से बाहर निकलना चाहिए। यह बरबाद कोड के लिए एक आदर्श नुस्खा है। यदि, हालाँकि, आप एक अपवाद को फेंककर त्रुटि का संकेत देते हैं, तो उपभोग कोड तुरंत अपवाद को संभालने का विकल्प चुन सकता है, या फ़ंक्शन कॉल के दौरान भी इसे उपयुक्त स्तर तक बुलबुला कर सकता है। यह बहुत क्लीनर कोड के लिए बनाता है।

वैचारिक रूप से, यदि आप एक फ़ाइल खोलते हैं और कुछ गलत हो जाता है, तो एक मान (यहां तक ​​कि NULL) वापस करना गलत है। आपके पास वापस लौटने के लिए कुछ भी नहीं है, क्योंकि आपका ऑपरेशन पूरा नहीं हुआ है। रिटर्निंग NULL, "मैंने फ़ाइल को सफलतापूर्वक पढ़ा है, और यहाँ इसमें क्या है - कुछ भी नहीं" के वैचारिक समतुल्य है। यदि ऐसा है जिसे आप व्यक्त करना चाहते हैं (अर्थात, यदि NULL ऑपरेशन में प्रश्न के लिए वास्तविक परिणाम के रूप में समझ में आता है), तो हर तरह से NULL लौटाते हैं, लेकिन यदि आप त्रुटि का संकेत देना चाहते हैं, तो अपवादों का उपयोग करें।

ऐतिहासिक रूप से, त्रुटियों की रिपोर्ट इस तरह से की गई थी क्योंकि C जैसी प्रोग्रामिंग भाषाओं में भाषा में निर्मित अपवाद हैंडलिंग नहीं है, और अनुशंसित तरीका (लंबी छलांग का उपयोग करके) थोड़ा बालों वाला और काउंटर-सहज ज्ञान युक्त है।

समस्या का एक रखरखाव पक्ष भी है: अपवादों के साथ, आपको विफलता को संभालने के लिए अतिरिक्त कोड लिखना होगा; यदि आप नहीं करते हैं, तो कार्यक्रम जल्दी और कठिन (जो अच्छा है) विफल हो जाएगा। यदि आप NULL को सिग्नल त्रुटियों पर लौटाते हैं, तो प्रोग्राम के लिए डिफ़ॉल्ट व्यवहार त्रुटि को अनदेखा करना है और बस ले जाने के लिए है, जब तक कि यह सड़क के नीचे अन्य समस्याओं की ओर नहीं जाता है - भ्रष्ट डेटा, segfaults, NullReferenceException, भाषा पर निर्भर करता है। त्रुटि को जल्दी और जोर से संकेत देने के लिए, आपको अतिरिक्त कोड लिखना होगा, और अनुमान लगाना होगा कि: यह वह हिस्सा है जो तंग डेडलाइन पर होने पर बाहर निकल जाता है।


1

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

यदि आप अशक्त बिंदुओं को एक मान्य मामले के रूप में अनुमति देते हैं, तो यह एक विशेष मामला है। आपको विशेष-केस हैंडलिंग तर्क की आवश्यकता होती है, अक्सर विभिन्न स्थानों में। यह अतिरिक्त जटिलता है।

यह संभावित रूप से अशक्त बिंदुओं से संबंधित है या नहीं, यदि आप असाधारण मामलों को संभालने के लिए अपवाद थ्रो का उपयोग नहीं करते हैं , तो आपको उन असाधारण मामलों को किसी अन्य तरीके से संभालना होगा। आमतौर पर, प्रत्येक फ़ंक्शन कॉल में उन असाधारण मामलों की जांच होनी चाहिए, या तो फ़ंक्शन कॉल को अनुचित रूप से रोकने के लिए, या फ़ंक्शन के बाहर निकलने पर विफलता के मामले का पता लगाने के लिए। यह अतिरिक्त जटिलता है जिसे अपवादों का उपयोग करके टाला जा सकता है।

अधिक जटिलता आमतौर पर अधिक त्रुटियों का मतलब है।

डेटा संरचनाओं में अशक्त बिंदुओं का उपयोग करने के लिए विकल्प (जैसे किसी लिंक की गई सूची के प्रारंभ / अंत को चिह्नित करना) में प्रहरी वस्तुओं का उपयोग करना शामिल है। ये बहुत कम जटिलता के साथ समान कार्यक्षमता दे सकते हैं। हालांकि, जटिलता को प्रबंधित करने के अन्य तरीके हो सकते हैं। एक तरीका यह है कि एक संभावित पॉइंटर को स्मार्ट पॉइंटर क्लास में लपेटा जाए ताकि नल की जाँच केवल एक ही स्थान पर हो।

जब यह पता चला है तो अशक्त सूचक के बारे में क्या करना है? यदि आप असाधारण-मामले से निपटने में निर्माण नहीं कर सकते हैं, तो आप हमेशा एक अपवाद फेंक सकते हैं, और उस विशेष-मामले को कॉल करने वाले को प्रभावी ढंग से सौंप सकते हैं। और यह ठीक है कि कुछ भाषाएं डिफ़ॉल्ट रूप से क्या करती हैं जब आप एक शून्य सूचक को रोकते हैं।


1

C ++ के लिए विशिष्ट है, लेकिन वहाँ शून्य संदर्भों को हटा दिया जाता है क्योंकि C ++ में शून्य शब्दार्थ सूचक प्रकारों से जुड़े होते हैं। एक फ़ाइल ओपन फंक्शन के लिए यह काफी उचित है कि वह विफल हो जाए और अशक्त सूचक को लौटा दे; वास्तव में fopen()फ़ंक्शन ठीक यही करता है।


दरअसल, आप सी में एक अशक्त संदर्भ के साथ खुद को पाते हैं ++, क्योंकि अपने कार्यक्रम है पहले से ही टूट
काज ड्रैगन

1

यह भाषा पर निर्भर करता है।

उदाहरण के लिए, ऑब्जेक्टिव-सी आपको समस्याओं के बिना एक अशक्त (शून्य) वस्तु पर एक संदेश भेजने की अनुमति देता है। निल के रूप में अच्छी तरह से रिटर्न करने के लिए कॉल और एक भाषा सुविधा माना जाता है।

मुझे व्यक्तिगत रूप से यह पसंद है क्योंकि आप उस व्यवहार पर भरोसा कर सकते हैं और उन सभी दोषपूर्ण नेस्टेड if(obj == null)निर्माणों से बच सकते हैं ।

उदाहरण के लिए:

if (myObject != nil && [myObject doSomething])
{
    ...
}

इसे छोटा किया जा सकता है:

if ([myObject doSomething])
{
    ...
}

संक्षेप में, यह आपके कोड को अधिक पठनीय बनाता है।


0

जब तक आप इसे डॉक्यूमेंट नहीं करते, मैं एक हूट नहीं देता, चाहे आप एक शून्य लौटा दें या एक अपवाद फेंक दें।


और इसे भी नाम दें: GetAddressMaybeया GetSpouseNameOrNull
11'11

-1

अशक्त संदर्भ आमतौर पर होता है क्योंकि प्रोग्राम लॉजिक में कुछ छूट गया था, अर्थात: आपको कोड के उस ब्लॉक के लिए आवश्यक सेट-अप के माध्यम से जाने के बिना कोड की एक पंक्ति मिल गई थी।

दूसरी ओर, यदि आप किसी चीज के अपवाद को फेंकते हैं तो इसका मतलब है कि आपने माना है कि कार्यक्रम के सामान्य संचालन में एक विशेष स्थिति उत्पन्न हो सकती है, और इसे संभाला जा रहा है।


2
बड़ी संख्या में कारणों से एक अशक्त संदर्भ "घटित" हो सकता है, उनमें से बहुत कम कुछ भी याद किए जाने से संबंधित हैं। हो सकता है कि आप इसे एक अशक्त संदर्भ अपवाद के साथ भ्रमित कर रहे हों ।
Aaronaught

-1

अशक्त संदर्भ अक्सर बहुत उपयोगी होते हैं: उदाहरण के लिए, एक लिंक की गई सूची में एक तत्व में कुछ उत्तराधिकारी या कोई उत्तराधिकारी हो सकता है। null"कोई उत्तराधिकारी" के लिए उपयोग करना पूरी तरह से प्राकृतिक है। या, किसी व्यक्ति का जीवनसाथी हो सकता है या नहीं - null"व्यक्ति का कोई जीवनसाथी नहीं है" के लिए उपयोग करना पूरी तरह से स्वाभाविक है, कुछ होने की तुलना में बहुत अधिक प्राकृतिक "कोई जीवनसाथी नहीं है" - विशिष्ट मूल्य जिसका Person.Spouseसदस्य उल्लेख कर सकता है।

लेकिन: कई मान वैकल्पिक नहीं हैं । एक सामान्य OOP कार्यक्रम में, मैं कहूंगा कि आधे से अधिक संदर्भ nullआरंभीकरण के बाद नहीं हो सकते हैं , या कार्यक्रम विफल हो जाएगा। अन्यथा कोड को if (x != null)चेक के साथ रिडल्ड करना होगा । तो हर संदर्भ को डिफ़ॉल्ट रूप से क्यों अशक्त होना चाहिए ? यह वास्तव में दूसरा रास्ता होना चाहिए: चर डिफ़ॉल्ट रूप से गैर-अशक्त होना चाहिए, और आपको स्पष्ट रूप से "ओह कहना चाहिए, और यह मान भी हो सकता nullहै"।


क्या इस चर्चा से कुछ है जो आप अपने उत्तर में वापस जोड़ना चाहते हैं? यह टिप्पणी धागा थोड़ा गर्म हो गया, और हम इसे साफ करना चाहेंगे। किसी भी विस्तारित चर्चा को चैट में लिया जाना चाहिए ।

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

-1

आपका प्रश्न भ्रामक है। क्या आपका मतलब एक शून्य संदर्भ अपवाद है (जो वास्तव में डी के प्रयास के कारण होता हैसंदर्भ शून्य)? उस प्रकार का अपवाद न करने का स्पष्ट कारण यह है कि यह आपको कोई जानकारी नहीं देता है कि क्या गलत हुआ है, या यहां तक ​​कि जब - कार्यक्रम में किसी भी बिंदु पर शून्य करने के लिए मूल्य निर्धारित किया जा सकता था। आप लिखते हैं "यदि मैं एक ऐसी फ़ाइल का उपयोग करने का अनुरोध करता हूं जो मौजूद नहीं है, तो मैं अपवाद या अशक्त संदर्भ प्राप्त करने के लिए पूरी तरह से खुश हूं" - लेकिन आपको ऐसा कुछ प्राप्त करने के लिए पूरी तरह से खुश नहीं होना चाहिए जो कारण का कोई संकेत नहीं देता है । स्ट्रिंग में कहीं भी "डर्फरेंस नल करने का प्रयास किया गया था" इसमें पढ़ने या गैर-मौजूदा फ़ाइलों का कोई उल्लेख है। शायद आपका मतलब है कि आप रीड कॉल से रिटर्न वैल्यू के रूप में शून्य पाने के लिए पूरी तरह से खुश होंगे - यह एक बहुत अलग बात है, लेकिन यह अभी भी आपको इस बारे में कोई जानकारी नहीं देता है कि रीड विफल क्यों हुआ; यह


नहीं, मेरा मतलब एक अशक्त संदर्भ अपवाद नहीं है। सभी भाषाओं में मुझे पता है कि असंगठित लेकिन घोषित चर कुछ अशक्त हैं।
davidk01

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

1
"... लेकिन इसके बजाय रैपर ऑब्जेक्ट्स का उपयोग करें जो वैकल्पिक रूप से एक मूल्य शामिल कर सकते हैं ।" जो स्पष्ट रूप से एक अशक्त प्रकार की तरह कुछ भी नहीं है
एरोन ने

1
हैस्केल में एक असिंचित चर जैसी कोई चीज नहीं होती है। आप संभावित रूप से एक आईओआरएफ की घोषणा कर सकते हैं और इसे प्रारंभिक मूल्य के रूप में किसी के साथ नहीं दे सकते हैं, लेकिन यह किसी अन्य भाषा में एक चर घोषित करने और इसे अनैतिक रूप से छोड़ने का एनालॉग है जो इसे सभी समान समस्याओं के साथ लाता है। IO मोनाड हैस्केल प्रोग्रामर्स के बाहर विशुद्ध रूप से कार्यात्मक कोर में काम करने से संदर्भ प्रकारों की कोई पुनरावृत्ति नहीं होती है, इसलिए कोई संदर्भ संदर्भ समस्या नहीं है।
davidk01

1
यदि आपके पास एक असाधारण "मिसिंग" मूल्य है, तो यह वास्तव में एक असाधारण "अशक्त" मूल्य के समान है - यदि आपके पास इसे संभालने के लिए समान उपकरण उपलब्ध हैं। यह एक महत्वपूर्ण "अगर" है। आपको उस मामले को किसी भी तरह से संभालने के लिए अतिरिक्त जटिलता की आवश्यकता है। हास्केल में, पैटर्न मिलान और प्रकार प्रणाली उस जटिलता को प्रबंधित करने में मदद करने का एक तरीका प्रदान करती है। हालांकि, अन्य भाषाओं में जटिलता के प्रबंधन के लिए अन्य उपकरण हैं। अपवाद एक ऐसा उपकरण है।
स्टीव ३
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.