तार्किक ऑपरेटरों के रूप में ट्राई / कैच के उपयोग के खिलाफ या उसके खिलाफ तर्क [बंद]


36

मैंने अभी-अभी अपनी कंपनियों के ऐप में कुछ प्यारे कोड खोजे हैं, जो लॉजिकल-ऑपरेटर्स के रूप में Try-Catch ब्लॉकों का उपयोग करते हैं।
मतलब, "कुछ कोड करते हैं, अगर वह इस त्रुटि को फेंकता है, तो इस कोड को करें, लेकिन अगर यह त्रुटि फेंकता है तो इसके बजाय यह 3 कार्य करें"।
यह "अंतत:" का उपयोग "और" कथन के रूप में होता है।
मुझे पता है कि यह स्वाभाविक रूप से गलत है, लेकिन इससे पहले कि मैं एक लड़ाई चुनता हूं मैं कुछ अच्छी तरह से सोचा तर्क के लिए उम्मीद कर रहा था।
और हे, अगर आपके पास इस तरीके से ट्राई-कैच के उपयोग के लिए तर्क हैं, तो कृपया बताएं।

जो लोग आश्चर्यचकित हैं, उनके लिए भाषा C # है और प्रश्न में कोड लगभग 30+ पंक्तियों का है और विशिष्ट अपवादों की तलाश में है, यह सभी अपवादों को नहीं संभाल रहा है।


13
मेरे पास केवल इस प्रथा के खिलाफ तर्क हैं , और जब से आप पहले से ही आश्वस्त हैं कि यह एक बुरा विचार है, मैं उन्हें पोस्ट करने के लिए परेशान करने वाला नहीं हूं।
FrustratedWithFormsDesigner

15
@FrustratedWIthFormsDesigner: यह गलत तर्क है। उन लोगों के बारे में जो आश्वस्त नहीं हैं? मेरे वास्तविक प्रश्न के बारे में क्या है जहाँ मैं विशेष रूप से कारण पूछता हूँ क्योंकि मैं वास्तव में "क्यों" नहीं बता सकता कि मुझे पता है कि यह गलत है।
जेम्स पी। राइट

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

11
मुझे आशा है कि वे वास्तव में "अंततः" ब्लॉक को "और" के रूप में उपयोग नहीं करते हैं क्योंकि "अंत" ब्लॉक हमेशा पूर्ववर्ती कोड के बाद चलाया जाता है, बिना किसी अपवाद के फेंके जाने के बावजूद।
jimreed'

2
वे किस भाषा का उपयोग कर रहे हैं? ओकेएमएल, यह पूरी तरह से ठीक है, जहां मानक पुस्तकालय नियमित रूप से अपवादों को फेंकता है। अपवाद हैंडलिंग वहाँ बहुत सस्ता है। लेकिन यह CLI या JVM में उतना कुशल नहीं होगा।
एसके-लॉजिक

जवाबों:


50

फ्लो कंट्रोल (निश्चित रूप से सी # और जावा के लिए) को संभालने के लिए अपवाद हैंडलिंग एक महंगा तरीका है।

रनटाइम काफी काम करता है जब एक अपवाद ऑब्जेक्ट का निर्माण किया जाता है - स्टैक ट्रेस को एक साथ प्राप्त करना, यह पता लगाना कि जहां अपवाद को संभाला जाता है और अधिक।

यह सब मेमोरी और सीपीयू संसाधनों में खर्च होता है जिसे फ्लो कंट्रोल स्टेटमेंट का उपयोग फ्लो कंट्रोल के लिए किया जाता है, तो इसे विस्तारित करने की आवश्यकता नहीं होती है।

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

इन दोनों के अलावा, कोड पढ़ने वाले अन्य लोगों की बात है। इस तरह से अपवादों का उपयोग करना कुछ ऐसा नहीं है जो अधिकांश प्रोग्रामर अपेक्षा करेंगे, इसलिए पठनीयता और आपके कोड को समझने में कितना नुकसान होता है। जब कोई "अपवाद" देखता है, तो एक सोचता है - कुछ बुरा हुआ, कुछ ऐसा जो सामान्य रूप से नहीं होना चाहिए। तो, इस तरह से अपवादों का उपयोग करना केवल सादा भ्रम है।


1
प्रदर्शन के बारे में एक अच्छा बिंदु, हालांकि यह भी मंच की बारीकियों पर निर्भर करेगा।
FrustratedWithFormsDesigner

4
यदि यह केवल नकारात्मक पक्ष है, तो अच्छी तरह से धन्यवाद - अगर मैं इसे बेहतर कोड खरीदता हूं, तो मैं किसी भी दिन प्रदर्शन छोड़ दूंगा (प्रदर्शन-महत्वपूर्ण रास्तों को छोड़कर) -critical)।

5
@ डायलेन - नहीं, केवल नकारात्मक पक्ष।
ओड

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

4
"फ्लो कंट्रोल को संभालने के लिए अपवाद हैंडलिंग एक महंगा तरीका है।" अजगर के लिए झूठी।
S.Lott

17

मैंने अभी-अभी अपनी कंपनियों के ऐप में कुछ प्यारे कोड खोजे हैं, जो लॉजिकल-ऑपरेटर्स के रूप में Try-Catch ब्लॉकों का उपयोग करते हैं। मतलब, "कुछ कोड करते हैं, अगर वह इस त्रुटि को फेंकता है, तो इस कोड को करें, लेकिन अगर यह त्रुटि फेंकता है तो इसके बजाय यह 3 कार्य करें"। यह "अंतत:" का उपयोग "और" कथन के रूप में होता है। मुझे पता है कि यह स्वाभाविक रूप से गलत है ...

तुम्हें कैसे पता? मैंने "ज्ञान" के सभी प्रकार छोड़ दिए और अब केवल यह मानता हूं कि सबसे सरल कोड सबसे अच्छा है। मान लीजिए कि आप एक स्ट्रिंग को एक वैकल्पिक में बदलना चाहते हैं जो पार्स विफल होने पर खाली है। इसमें कुछ भी गलत नहीं है:

try { 
    return Optional.of(Long.valueOf(s)); 
} catch (NumberFormatException) { 
    return Optional.empty(); 
}

मैं "असाधारण परिस्थितियों के लिए अपवाद हैं" की सामान्य व्याख्या से पूरी तरह असहमत हूं। जब कोई फ़ंक्शन उपयोग करने योग्य मान नहीं लौटा सकता है या कोई विधि अपनी पोस्ट की शर्तों को पूरा नहीं कर सकती है, तो अपवाद को फेंक दें। इससे कोई फर्क नहीं पड़ता कि प्रदर्शन अपवाद समस्या होने तक कितनी बार इन अपवादों को फेंक दिया जाता है।

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

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


4
मुझे लगता है कि यह वास्तव में एक बहुत अच्छा तर्क है। आपका कोड साफ और संक्षिप्त है और समझ में आता है कि यह क्या कर रहा है। यह वास्तव में मेरे द्वारा देखे जा रहे कोड में समान है, केवल यह बहुत अधिक जटिल है, नेस्टेड है और कोड की 30+ पंक्तियों को फैलाता है।
जेम्स पी। राइट

@ नाम: यदि आप कुछ छोटे तरीकों को निकालते हैं तो कोड अच्छा लगता है।
केविन क्लाइन

1
एक तर्क दे सकता है कि जावा वास्तव में C # के TryParse की तरह कुछ और उपयोग कर सकता है। C # में वह कोड होगा int i; if(long.TryParse(s, out i)) return i; else return null;। अगर स्ट्रिंग को पार्स नहीं किया जा सकता है, तो TryParse गलत रिटर्न देता है। यदि इसे पार्स किया जा सकता है तो यह पार्सिंग के परिणामों को आउटपुट तर्क सेट करता है और सच लौटाता है। कोई अपवाद नहीं होता है, (यहां तक ​​कि आंतरिक रूप से TryParse में) और विशेष रूप से कोई अपवाद नहीं है जो प्रोग्रामर त्रुटि का अर्थ है, जैसे .NET FormatExceptionहमेशा इंगित करता है।
केविन कैथार्ट

1
@ केविन कैथार्ट, लेकिन यह बेहतर क्यों है? कोड जो नंबरफ़ॉर्मैट अपवाद को पकड़ता है, मेरे लिए बहुत अधिक स्पष्ट है, फिर अशक्त के लिए TryParse के परिणाम की जांच करना।
विंस्टन एवर्ट

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

12

डिबग और रखरखाव का काम बहुत मुश्किल होता है जब अपवादों का उपयोग करके नियंत्रण प्रवाह किया जाता है।

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

  • अक्षमता अतिरिक्त हुप्स है कि अपवाद के लिए आवश्यक अपेक्षाकृत कठिन संदर्भ परिवर्तनों को सुरक्षित रूप से करने के लिए पर्यावरण को कूदना पड़ता है, इंस्ट्रूमेंटेशन और संसाधनों की आवश्यकता होती है।

  • डिबग कठिनाइयाँ कभी-कभी उपयोगी होती हैं (जब किसी प्रोग्राम को डीबग करने की कोशिश की जाती है) जानकारी अपवाद होने पर खिड़की से बाहर फेंक दी जाती है। आप रन-टाइम व्यवहार को समझने के लिए प्रासंगिक प्रोग्राम या इतिहास का ट्रैक खो सकते हैं

  • रखरखाव की समस्याएं अपवाद प्रवाह के माध्यम से निष्पादन का प्रवाह कठिन है। इसके अलावा, एक अपवाद ब्लैक-बॉक्स प्रकार कोड के अंदर से फेंक दिया जा सकता है, जो अपवाद को फेंकने के तरीके को समझने में आसान व्यवहार नहीं कर सकता है।

  • इस तरह से निर्मित गरीब डिजाइन निर्णय कार्यक्रम मन के एक फ्रेम को प्रोत्साहित करते हैं, जो ज्यादातर मामलों में, आसानी से समस्याओं को हल करने के लिए आसानी से मैप नहीं करता है। अंतिम कार्यक्रम की जटिलता प्रोग्रामर को इसके निष्पादन को पूरी तरह से समझने से हतोत्साहित करती है, और ऐसे फैसले लेने के लिए प्रोत्साहित करती है जो दीर्घकालिक लागतों के साथ अल्पकालिक सुधार लाते हैं।


10

मैंने इस पैटर्न को कई बार इस्तेमाल किया है।

2 प्रमुख समस्याएं हैं:

  • यह बहुत महंगा है (अपवाद ऑब्जेक्ट का इंस्टेंटेशन, कॉल स्टैक आदि को इकट्ठा करना)। कुछ संकलक वास्तव में इसे दूर करने में सक्षम हो सकते हैं, लेकिन मैं इस मामले में उस पर भरोसा नहीं करूंगा, क्योंकि अपवाद इस तरह के उपयोग के लिए नहीं हैं, इसलिए आप लोगों से इसके लिए अनुकूलन की उम्मीद नहीं कर सकते।
  • नियंत्रण प्रवाह के अपवादों का उपयोग करना वास्तव में एक छलांग है, बहुत कुछ जैसे goto। कई कारणों से कूदना हानिकारक माना जाता है। उनका उपयोग किया जाना चाहिए, यदि सभी विकल्पों में काफी नुकसान हैं। वास्तव में, मेरे सभी कोड में मुझे केवल 2 मामले याद हैं, जहां कूद स्पष्ट रूप से सबसे अच्छा समाधान था।

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

1
@jsternbarg: हाँ, अगर / और मशीन स्तर पर छलांग लगाने के लिए वास्तव में हैं, लेकिन भाषा के स्तर पर, कूद लक्ष्य अगला बयान है, जबकि लूप के मामले में, यह वर्तमान कथन है। मेरा तर्क है, कि यह एक कदम से अधिक है, एक छलांग की तुलना में;)
back2dos

9

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

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

मैंने ऐसा समय देखा है जब यह क्वेरी टेबल जैसी कुछ बेवकूफी करने के लिए तेज़ होता है, जो यह पता लगाने की तुलना में नहीं थे कि क्या एक तालिका PHP + MySQL में मौजूद है ( सवाल जहां मैं यह मान रहा हूं कि यह वास्तव में नकारात्मक वोटों के साथ मेरा एकमात्र स्वीकृत उत्तर है) ।

उन सभी ने कहा, अपवादों का उपयोग कई कारणों से सीमित होना चाहिए:

  1. नेस्टेड अपवादों की आकस्मिक निगलने। यह प्रमुख है। यदि आप कुछ गहराई से नेस्टेड अपवाद को पकड़ते हैं, जिसे कोई और संभालने की कोशिश कर रहा है, तो आपने अपने साथी प्रोग्रामर (शायद आप भी!) को पैर में गोली मार दी है।
  2. टेस्ट गैर-स्पष्ट हो जाते हैं। कोड का एक ब्लॉक जिसमें इसका अपवाद है, इसके साथ गलत कई चीजों में से एक हो सकता है। एक बूलियन, दूसरी ओर, जबकि सैद्धांतिक रूप से यह डिबग करने के लिए कष्टप्रद हो सकता है, यह आमतौर पर नहीं है। यह विशेष रूप से सच है क्योंकि try...catchनियंत्रण प्रवाह के पालनकर्ता आम तौर पर (मेरे अनुभव में) "ब्लॉक में कम से कम कोड" दर्शन का पालन नहीं करते हैं।
  3. यह एक else ifब्लॉक के लिए अनुमति नहीं देता है । पर्याप्त ने कहा (और यदि कोई "लेकिन वे अलग-अलग अपवाद वर्गों का उपयोग कर सकते हैं" के साथ काउंटर्स करते हैं, तो मेरी प्रतिक्रिया है "अपने कमरे में जाओ और जब तक आपने जो कुछ भी कहा है उसके बारे में नहीं सोचा है।"
  4. यह व्याकरणिक रूप से भ्रामक है। Exception, शेष दुनिया के लिए (जैसा कि try...catchनियंत्रण-प्रवाह दर्शन के अनुयायियों में नहीं है ), इसका मतलब है कि कुछ अस्थिर (हालांकि पुनर्प्राप्त करने योग्य) स्थिति में प्रवेश कर गया है। अस्थिर अवस्थाएं बीएडी हैं और हमें रात को यह सब रखना चाहिए अगर हमारे पास वास्तव में परिहार्य अपवाद हैं (यह वास्तव में मुझे बाहर निकालता है, कोई झूठ नहीं)।
  5. यह आम कोडिंग शैली के अनुरूप नहीं है। हमारा काम, हमारे कोड के साथ और हमारे UI के साथ दुनिया को यथासंभव स्पष्ट करना है। try...catchनियंत्रण-प्रवाह के खिलाफ जाता है जिसे आमतौर पर सबसे अच्छा व्यवहार माना जाता है। इसका मतलब यह है कि किसी नए व्यक्ति के लिए परियोजना को सीखने में अधिक समय लगता है, जिसका अर्थ है बिना किसी लाभ के मानव-घंटे की संख्या में वृद्धि।
  6. इससे अक्सर कोड दोहराव होता है। अंत में ब्लॉक, हालांकि यह कड़ाई से आवश्यक नहीं है, सभी झूलने वाले बिंदुओं को हल करने की आवश्यकता है जो बाधित कोशिश ब्लॉक द्वारा खुले छोड़ दिए गए थे। इसलिए ब्लॉक करने की कोशिश करें। इसका मतलब है कि आप एक हो सकता है try{ obj.openSomething(); /*something which causes exception*/ obj.doStuff(); obj.closeSomething();}catch(Exception e){obj.closeSomething();}। अधिक पारंपरिक, if...elseपरिदृश्य में, closeSomething()कॉपी और पेस्ट नौकरी होने की संभावना कम (फिर से, व्यक्तिगत अनुभव) है। (जाहिर है, यह विशेष तर्क उन लोगों के साथ अधिक है जो मुझे वास्तविक दर्शन से ही मिले हैं)।

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

4 और 5 मुझे एक ही बिंदु लगते हैं। अगर आपकी भाषा अजगर है तो 3-6 लागू न करें। 1 और 2 संभावित मुद्दे हैं, लेकिन मुझे लगता है कि उन्हें कोशिश ब्लॉक में कोड को कम करके नियंत्रित किया जाता है।
विंस्टन एवर्ट

1
@ आइंस्टन मैं असहमत हूं। 1 और 2 प्रमुख मुद्दे हैं, जो बेहतर कोडिंग मानकों से कम हो गए हैं, फिर भी एक आश्चर्य है कि क्या केवल शुरू करने के लिए संभावित त्रुटि से बचने के लिए बेहतर नहीं हो सकता है। 3 लागू होता है अगर आपकी भाषा पायथन है। 4-5 पायथन के लिए भी आवेदन कर सकते हैं, लेकिन उनके पास नहीं है। 4 और 5 बहुत अलग बिंदु हैं - भ्रामक शैलीगत मतभेदों से अलग है। भ्रामक कोड एक वाहन को शुरू करने के लिए ट्रिगर का नामकरण जैसा कुछ कर सकता है, "स्टॉप बटन।" दूसरी ओर, Stylistically, यह सी में सभी ब्लॉक इंडेंटेशन से बचने के लिए भी अनुरूप हो सकता है
c Sepenpoole

3) पायथन में अपवादों के लिए एक और ब्लॉक है। यह आम तौर पर 1 और 2 के लिए आपको मिलने वाली समस्याओं से बचने के लिए बड़े पैमाने पर सहायक है
विंस्टन एवर्ट

1
बस स्पष्ट होने के लिए, मैं अपवादों का उपयोग करने की वकालत नहीं कर रहा हूं आपके सामान्य प्रवाह नियंत्रण तंत्र हैं। मैं किसी भी प्रकार की "विफलता" मोड के लिए अपवाद को फेंकने की वकालत करता हूं, चाहे वह कितना भी मामूली क्यों न हो। मुझे लगता है कि अपवाद हैंडलिंग संस्करण क्लीनर है और बग्स को छिपाने की संभावना कम है, फिर रिटर्न वैल्यू चेकिंग संस्करण। और आदर्श रूप से, मैं नेस्टेड त्रुटियों को पकड़ने के लिए भाषाओं को कठिन बनाना चाहूंगा।
विंस्टन एवर्ट

4

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


2

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

मेरा मतलब है, कई संभावनाएं हैं:

  1. वे अक्षम हैं
  2. उन्होंने जो किया, उसके लिए पूरी तरह से मान्य कारण है, जो शायद पहली नजर में दिखाई न दे।
  3. कभी-कभी यह स्वाद का सवाल है और कुछ जटिल कार्यक्रम प्रवाह को सरल कर सकता है।
  4. यह अतीत का अवशेष है जिसे किसी ने अभी तक नहीं बदला और अगर कोई ऐसा करता है तो वे खुश होंगे

... मुझे लगता है कि ये सभी समान रूप से संभव हैं। तो बस उन्हें अच्छी तरह से पूछें।


1

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

संपादित करें:

कारण: आप यह तर्क दे सकते हैं कि यदि आप सशर्त ऑपरेटर के रूप में ट्राई कैच का उपयोग करते हैं, तो आप वास्तविक अपवादों को कैसे देखते हैं?


2
ओपी कारण / तर्क पूछ रहा है। आपने कोई प्रदान नहीं किया है।
ऊदबिलाव

"आप यह तर्क दे सकते हैं कि यदि आप सशर्त ऑपरेटर के रूप में ट्राई कैच का उपयोग करते हैं, तो आप वास्तविक अपवादों के लिए कैसे जा रहे हैं?" - catch"गैर-वास्तविक" अपवादों को पकड़ने वाले से भिन्न खंड में उन वास्तविक अपवादों को पकड़ने से?

@delnan - धन्यवाद! आपने एक बिंदु सिद्ध किया है जिसे मैं बनाने जा रहा था। यदि किसी व्यक्ति ने उत्तर दिया कि आपने अभी-अभी मेरे कारण और ओलेड के बारे में क्या कहा है, तो मैं सिर्फ इसलिए बात करना बंद कर दूंगा कि वह उन कारणों की तलाश नहीं कर रहा है, जो अभी-अभी ज़िद्दी हैं और मैं हठ के साथ अपना समय बर्बाद नहीं करता।
एजेसी

आप मुझे स्टूडबोर्न कह रहे हैं क्योंकि मैं यहां सूचीबद्ध कुछ तर्कों में खामियों को इंगित करता हूं? ध्यान दें कि मेरे पास यहां बताए गए अन्य बिंदुओं के खिलाफ कहने के लिए कुछ नहीं है। मैं प्रवाह नियंत्रण के लिए अपवादों का उपयोग करने का प्रशंसक नहीं हूं (हालांकि मैं विवरण के बिना कुछ भी निंदा नहीं करूंगा, इसलिए ओपी द्वारा विस्तार के लिए मेरी क्वेरी), मैं केवल शैतान का वकील खेल रहा हूं।

1
सशर्त ऑपरेटर के रूप में ट्राइ-कैच का उपयोग करना किसी भी तरह से इसे "वास्तविक" अपवादों को पकड़ने के लिए काम करने से रोकता है।
विंस्टन एवर्ट

1

अपवाद तब होता है जब असाधारण चीज होती है। क्या प्रोग्राम नियमित वर्कफ़्लो के अनुसार असाधारण है?


1
पर क्यों? सवाल का मुद्दा यह है कि (या क्यों नहीं) अपवाद केवल इसके लिए अच्छे हैं।
विंस्टन एवर्ट

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

1
-1: tautological statement
चावल का आटा कुकीज

1

अपवादों का उपयोग करने का कारण:

  1. यदि आप एक असाधारण परिस्थिति को पकड़ना भूल जाते हैं, तो आपका कार्यक्रम मर जाएगा और स्टैक ट्रेस आपको बताएगा कि आखिर क्यों। यदि आप एक अपवाद परिस्थिति के लिए वापसी मूल्य को संभालना भूल जाते हैं तो यह नहीं बता रहा है कि आपका कार्यक्रम कितनी दूर तक गलत व्यवहार प्रदर्शित करेगा।
  2. रिटर्न वैल्यू का उपयोग केवल तभी काम करता है जब कोई सेंटिनल वैल्यू है, जिसे आप वापस कर सकते हैं। यदि सभी संभावित रिटर्न मान पहले से ही मान्य हैं, तो आप क्या करने जा रहे हैं?
  3. एक अपवाद अतिरिक्त जानकारी ले जाएगा कि क्या हुआ जो उपयोगी हो सकता है।

अपवादों का उपयोग न करने के कारण:

  1. कई भाषाओं को अपवाद बनाने के लिए डिज़ाइन नहीं किया गया है।
  2. स्टैक अप के ऊपर कई परतों की यात्रा करने वाले अपवाद असंगत स्थिति को उनके मद्देनजर छोड़ सकते हैं

अंततः:

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


0

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

तो प्लान ए का प्रयास करें , और यदि प्लान ए की मृत्यु हो जाती है, तो प्लान बी के साथ पकड़ें और चलाएं ... और यदि प्लान बी विफल हो जाता है, तो प्लान सी को किक करने के लिए अंत में उपयोग करें , जो ए या बी या पेज में विफल सेवाओं में से एक को ठीक कर देगा। मुझे।


0

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


"C ++ में मानक यह है कि अपवादों को वास्तव में असाधारण घटनाओं के लिए बचाया जाना चाहिए।" यह बकवास है। यहां तक ​​कि भाषा का आविष्कारक भी आपसे असहमत है
अराइक 2

-1

यह एक बुरी आदत है, लेकिन मैं इसे समय-समय पर अजगर में करता हूं। जैसे कि यह देखने के लिए कि क्या कोई फ़ाइल मौजूद है, मैं सिर्फ कोशिश करके उसे हटा दूं। यदि यह एक अपवाद फेंकता है, तो मैं पकड़ता हूं और यह जानने के लिए आगे बढ़ता हूं कि यह वहां नहीं था। <== (यदि कोई अन्य उपयोगकर्ता फ़ाइल का मालिक है, तो यह आवश्यक नहीं है, लेकिन मैं इसे उपयोगकर्ता के होम डायरेक्टरी में करता हूं ताकि यह SHOULDN'TT) हो।

फिर भी, इसका अत्यधिक उपयोग एक बुरा अभ्यास है।


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

यदि अजगर एक अपवाद सिर्फ इसलिए फेंक रहा है क्योंकि एक फ़ाइल मौजूद नहीं है, तो यह बुरी आदतों को प्रोत्साहित करने वाला प्रतीत होता है, जैसा कि डेलान का वर्णन है।
जोहानसन

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

1
यह एक बुरी आदत नहीं है। पायथन में इसकी अनुशंसित शैली।
विंस्टन एवर्ट

@ back2dos, क्या आप डेटाबेस / फ़ाइल सिस्टम के अन्य उपयोगकर्ताओं जैसे बाहरी संसाधनों से निपटने के दौरान इसे रोक सकते हैं?
विंस्टन एवर्ट

-1

मुझे पसंद है जिस तरह से Apple इसे परिभाषित करता है: अपवाद केवल प्रोग्रामर त्रुटियों और घातक रनटाइम त्रुटियों के लिए हैं। और त्रुटि कोड का उपयोग करें। यह मुझे यह तय करने में मदद करता है कि इसका उपयोग कब किया जाए, यह सोचकर कि "क्या यह एक प्रोग्रामर त्रुटि थी?"


-1

ऐसा लगता है कि एक गोटो कमांड नहीं है, जो किसी भाषा के ऊपर गोटो लॉजिक बनाने के लिए अपवाद हैंडलिंग का उपयोग करता है।

गोटो तर्क खराब होने के कई कारणों से, आप इस प्रश्न का उल्लेख कर सकते हैं: https://stackoverflow.com/questions/46586/goto-still-considered-harmful

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.