विकल्प / शायद एक अच्छा विचार क्यों माना जाता है और जाँच किए गए अपवाद नहीं हैं?


23

उदाहरण के लिए कुछ प्रोग्रामिंग भाषाओं जैसे कि स्काला में Optionटाइप्स (जिसे भी कहा जाता है Maybe) की अवधारणा है , जिसमें या तो मान हो सकता है या नहीं।

मैंने उनके बारे में जो पढ़ा है, उससे उन्हें इस मुद्दे से निपटने का एक बेहतर तरीका माना जाता है null, क्योंकि वे प्रोग्रामर को उन मामलों पर विचार करने के लिए स्पष्ट रूप से मजबूर करते हैं, जहां रनटाइम के दौरान सिर्फ उड़ाने के बजाय एक मूल्य नहीं हो सकता है।

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

क्या जाँच किए गए अपवादों के साथ कुछ अतिरिक्त समस्याएं हैं जो Optionटाइप नहीं हैं? या क्या ये विचार मेरे विचार के समान नहीं हैं, और विकल्पों के लिए स्पष्ट हैंडलिंग के लिए अच्छे कारण हैं और अपवाद के लिए नहीं?


Either e aडेटाटाइप भी देखें ।

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

जवाबों:


24

क्योंकि Options कंपोजेबल हैं। उपयोगी तरीकों पर की एक बहुत कुछ कर रहे हैं Optionकि आप संक्षिप्त कोड लिखने की अनुमति, जबकि अभी भी प्रवाह पर सटीक नियंत्रण की अनुमति देता है,: map, flatMap, toList, flattenऔर अधिक। यह इस तथ्य के कारण है कि Optionएक विशेष प्रकार का मोनाड है, कुछ वस्तुएं जिन्हें हम अच्छी तरह से जानते हैं कि कैसे रचना करना है। यदि आपके पास ये तरीके नहीं थे और हमेशा मैच मैच करना होता था Option, या isDefinedअक्सर कॉल करना होता था, तो वे लगभग उपयोगी नहीं होंगे।

इसके बजाय, जब जाँच किए गए अपवाद कुछ सुरक्षा जोड़ते हैं, तो बहुत कुछ नहीं है जो आप उन्हें पकड़ने के अलावा उनके साथ कर सकते हैं या उन्हें स्टैक को बुलबुला करने दें (प्रकार की घोषणा में जोड़े गए बॉयलरप्लेट के साथ)।


1
जांचे हुए अपवादों अधिक या कम एक ही तरीके से रचना ... के बीच का अंतर try {/* bunch of complex code involving calls to 50 different methods that may throw SomeCheckedException */} catch(SomeCheckedException e) {/* operation failed, do something */}और fromMaybe someDefaultValue (something >>= otherThing >>= ...50 other functions that may return Nothing...)वास्तव में क्या है? इस तथ्य के अलावा कि पूर्व आपको अधिक जानकारी देता है कि क्या गलत हुआ।
user253751

14

जबकि संबंधित, अपवाद और शायद वस्तुएं एक ही प्रकार की समस्याओं से नहीं निपटती हैं।

अपवाद

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

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

शायद वस्तुओं

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

शायद वस्तु का लाभ यह है कि आप स्पष्ट रूप से घोषणा करते हैं कि कुछ गलत हो सकता है। Haskell में, एक गैर शायद वस्तु का एक मूल्य होना चाहिए, या अन्यथा कार्यक्रम संकलित नहीं होगा।

अशक्त प्रकारों के साथ समस्या यह है कि आपको पूरी तरह से सुरक्षित रहने के लिए हर समय अशक्त होने की जांच करनी होगी। "कुछ गलत हो सकता है" राज्य डिफ़ॉल्ट एक है।

वापसी कोड के साथ समस्या + रेफरी के पास से गुजरती है कि वे ज्यादातर लोगों के लिए कम पठनीय हैं।


1
@MattFenwick प्रतिक्रिया के लिए धन्यवाद। आपको क्यों लगता है कि csv उदाहरण का कोई मतलब नहीं है? ओपी वास्तव में बॉयलरप्लेट-परिहार तकनीक के लिए नहीं पूछता है, और मुझे यह महसूस होता है कि इस प्रश्न के लिए एप्लास्टिक फंक्टर और मोनडर्स जैसी शब्दावली बहुत तकनीकी हो सकती है।
साइमन बर्गॉट

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

5
@Ind: सिर्फ इसलिए कि एक आईडीई व्यर्थ बॉयलरप्लेट पीढ़ी को स्वचालित कर सकता है इसका मतलब यह नहीं है कि व्यर्थ बॉयलरप्लेट एक दर्द नहीं है।
माइकल शॉ

2
@ घास: लेकिन दर्द दूर नहीं होता है। व्यर्थ बॉयलरप्लेट अभी भी है, बिना किसी कारण के कोड को अव्यवस्थित करना। यदि बॉयलरप्लेट का कोई कारण है, तो यह क्या है?
माइकल शॉ

2
@MichaelShaw यदि अपवाद व्यर्थ है, तो इसे हटा दें: स्थिति को अनदेखा करें या इसके बजाय त्रुटि मान लौटाएं। यदि यह बग या अपरिवर्तनीय स्थिति है: अनियंत्रित अपवाद का उपयोग करें। उदाहरण के मापदंडों के लिए जितना महत्वपूर्ण है उतना ही महत्वपूर्ण है, न कि बेकार बॉयलरप्लेट। यदि यह मौजूदा lib में खराब API है, तो अन्य lib का उपयोग करके, या खराब API को पीड़ित करते हुए, आवरण विधि / वर्ग पर विचार करें।
हाईड

1

क्योंकि Maybeआप त्रुटि को संभालने में देरी कर सकते हैं जब तक आपको वास्तव में मूल्य की आवश्यकता नहीं होती है (जो कुछ विधि कॉल दूर हो सकती है)

जबकि चेक किए गए अपवाद को कॉल स्थान पर नियंत्रित करने की आवश्यकता है

अपवादों के लिए केवल यह उल्टा है कि इस बारे में अधिक जानकारी दी जा सकती है कि यह विफल क्यों हुआ (जब तक कि कोई MaybeErrorएक त्रुटि के साथ फेंकने योग्य क्षेत्र के साथ विकसित नहीं होता है )


2
लेकिन मैं चेक किए गए अपवाद की हैंडलिंग को यह घोषित करके हटा सकता हूं कि मेरी विधि इस अपवाद को फेंकती है।
मैड साइंटिस्ट

1
@ मैडिसनस्टिस्ट जो केवल कॉल स्टैक पर जाता है, जबकि शायद सभी दिशाओं में जा सकता है
शाफ़्ट फ्रीक

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

@MadScientist: यदि कोई विधि कॉल "अमान्य मान" संकेत देता है, तो इसे निष्पादित करने के तुरंत बाद का कथन। इसके विपरीत, यदि कोई विधि एक अपवाद को फेंकती है जो तुरंत पकड़ा नहीं जाता है, तो कॉल के बाद के बयान को छोड़ दिया जाएगा। कॉल स्टैक अप चेक करने के अपवादों की जांच करना आम तौर पर बुराई है (और उनके साथ निपटने के लिए 'सबसे आसान तरीका नहीं होना चाहिए) क्योंकि कॉल करने वाले के लिए यह बताने का कोई तरीका नहीं है कि क्या शर्त का अर्थ उस विधि से अपेक्षित है, जिसे वह कहते हैं, या क्या यह एक अनपेक्षित स्थिति का प्रतिनिधित्व करता है जिसे कहा जाता है कि विधि बुलबुला फूट रही है।
सुपरकैट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.