फॉल-थ्रू स्विच स्टेटमेंट का उपयुक्त उपयोग


14

फ़ॉल-थ्रू (क्लासिक) स्विच स्टेटमेंट का उपयोग करना कब उचित है? क्या इस तरह के उपयोग की सिफारिश और प्रोत्साहन किया जाता है या इसे हर कीमत पर टाला जाना चाहिए?


सभी भाषाएं स्विच स्टेटमेंट पर गिरने की अनुमति नहीं देती हैं।
ऊद

@Oded, संपादित, "क्लासिक" शब्द जोड़ा गया। सभी भाषाओं के माध्यम से गिरने की अनुमति नहीं है, फिर भी मैं जोर देकर कहता हूं कि यह क्लासिक है)
शबूनक

3
अगर आप डफ्स डिवाइस के बारे में बात कर रहे हैं , तो यह एक बात है।
ऊद

6
@Oded: वह पहली चीज है जिसके बारे में ज्यादातर लोग सोचते हैं, लेकिन यह शायद ही "उपयुक्त" है। के अनुसार इस , गूंथा हुआ आटा खुद कहा "यह निश्चित रूप से चर्चा में एक बहस है कि क्या स्विच डिफ़ॉल्ट रूप से के माध्यम से गिर चाहिए प्रदान करता है, लेकिन मुझे यकीन है कि अगर तर्क के लिए या उसके खिलाफ है नहीं हूँ।"
ब्लूराजा - डैनी पफ्लुगुफ़ेक्ट

जवाबों:


15

यहां एक उदाहरण है जहां यह उपयोगी होगा।

public Collection<LogItems> GetAllLogItems(Level level) {
    Collection<LogItems> result = new Collection<LogItems>();
    switch (level) {
        // Note: fall through here is INTENTIONAL
        case All:
        case Info:
             result.Add(GetItemsForLevel(Info));
        case Warning:
             result.Add(GetItemsForLevel(Warning));
        case Error:
             result.Add(GetItemsForLevel(Error));
        case Critical:
             result.Add(GetItemsForLevel(Critical));
        case None:
    }
    return result;
}

इस तरह की बात (जहां एक मामले में अन्य शामिल है) बल्कि दुर्लभ है, मुझे लगता है, यही वजह है कि कुछ नई भाषाएं या तो फालोवर की अनुमति नहीं देती हैं या इसके लिए विशेष वाक्यविन्यास की आवश्यकता होती है।


13
यह उदाहरण, जबकि दिलचस्प है, अपेक्षित ऑल-कैप // INTENTIONAL FALL THROUGH HEREटिप्पणी का अभाव है ।
रसेल बोरोगोव

यह GetItemsForLevel(Info)कॉल इनवॉइस वगैरह के माध्यम से गिरने के साथ इस कोड को लिखना आसान है GetItemsForLevel(Warning)
कालेब

@ रसेलबोरोगोव: बिल्कुल सही।
विन्यासकर्ता

@ कालेब: इस मामले में, हाँ। लेकिन क्या होगा अगर कॉल थोड़ा अधिक जटिल थे? यह थोड़ा बालों वाला हो सकता है, जबकि गिरने से यह सरल लगता है। मुझे ध्यान देना चाहिए कि मैं वास्तव में गिरावट का उपयोग करने के पक्ष में नहीं हूं - मैं कह रहा हूं कि यह कुछ स्थितियों में उपयोगी हो सकता है।
विन्यासकर्ता

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

8

जब कुछ कार्यक्षमता को एक से अधिक मान के लिए लागू करना होता है, तो मैं उनका उपयोग करता हूं। उदाहरण के लिए, मान लीजिए कि आपके पास ऑपरेशनकोड नामक एक संपत्ति है। यदि कोड 1, 2, 3 या 4 के बराबर है, तो आप startOperationX () करना चाहते हैं। यदि यह 5 या 6 है, तो आप startOperationY () और 7 आप startOperationZ () करना चाहते हैं। कार्यक्षमता और विराम के साथ 7 पूर्ण मामले क्यों होते हैं जब आप फॉल-थ्रू का उपयोग कर सकते हैं?

मुझे लगता है कि यह कुछ स्थितियों में पूरी तरह से मान्य है, खासकर अगर यह 100 अगर-और बयानों से बचता है। =)


4
आप जो वर्णन कर रहे हैं वह एक ही कोड के switchसाथ एकाधिक cases से बंधा है। यह एक गिरावट के माध्यम से अलग है, जहां एक का निष्पादन caseअगले के breakबीच जारी रहता है क्योंकि उनके बीच की कमी है ।
ब्लर्टल

3
यह वास्तव में मायने नहीं रखता है, पतन-थ्रू सिर्फ ब्रेक स्टेटमेंट की कमी है इसलिए यह अगले मामले में "से होकर" गिरता है।
येट्रिक्स

मैं आपके उत्तर के परिदृश्य को फिर से दर्शाने के लिए कहूँगा।
Blrfl

2
@ वायट्रिक्स: मैं असहमत हूं। लगातार अलग-अलग मामलों में कोड के एक ही ब्लॉक को निष्पादित करने की तुलना में यह एक ब्रेक को छोड़ना है। एक नियमित है, दूसरा इससे (ime) दूर है - और गलत और अनपेक्षित नियंत्रण प्रवाह की संभावना बहुत अधिक है।
क्वेंटिन-स्टारिन

3
@qes हाँ, यह अलग है, लेकिन वे दोनों गिर-थ्रू हैं। उन्होंने पूछा कि कब / क्या यह उचित होगा। मैंने एक उदाहरण दिया कि यह कब होगा। यह एक सर्व-समावेशी उदाहरण नहीं था। भाषा के आधार पर, गिरावट से पहले बयान होने से काम नहीं चल सकता है। मुझे नहीं लगता कि यह C # stackoverflow.com/questions/174155/… के
Yatrix

8

मैंने उन्हें कभी-कभी उपयोग किया है, मुझे लगता है कि इसका हमेशा उचित उपयोग होता है - लेकिन केवल जब उचित टिप्पणी के साथ शामिल किया जाता है।


7

पतन के मामले पूरी तरह से ठीक हैं। मुझे अक्सर पता चलता है कि बहुत सारे स्थानों में एक एन्यूमरेशन का उपयोग किया जाता है, और जब आपको कुछ मामलों में अंतर करने की आवश्यकता नहीं होती है, तो फॉल-थ्रू लॉजिक का उपयोग करना आसान होता है।

उदाहरण के लिए (व्याख्यात्मक टिप्पणियों पर ध्यान दें):

public boolean isAvailable(Server server, HealthStatus health) {
  switch(health) {
    // Equivalent positive cases
    case HEALTHY:
    case UNDER_LOAD:
      return true;

    // Equivalent negative cases
    case FAULT_REPORTED:
    case UNKNOWN:
    case CANNOT_COMMUNICATE:
      return false;

    // Unknown enumeration!
    default:
      LOG.warn("Unknown enumeration " + health);
      return false;
  }
}

मुझे इस तरह का उपयोग पूरी तरह स्वीकार्य लगता है।


ध्यान दें कि case X: case Y: doSomething()और के बीच एक बड़ा अंतर है case X: doSomething(); case Y: doAnotherThing()। पहले में, इरादा काफी स्पष्ट है, जबकि दूसरे में, के माध्यम से गिरावट जानबूझकर हो सकती है या नहीं। मेरे अनुभव में, पहला उदाहरण कभी भी संकलक / कोड विश्लेषक में किसी भी चेतावनी को ट्रिगर नहीं करता है, जबकि दूसरा करता है। व्यक्तिगत रूप से, मैं केवल दूसरा उदाहरण "फॉल थ्रू" कहूंगा - हालांकि "आधिकारिक" परिभाषा के बारे में निश्चित नहीं है।
जेन्स बैनमैन

6

पर निर्भर करता है:

  • आपकी व्यक्तिगत प्राथमिकता
  • आपके नियोक्ता के कोडिंग मानक
  • जोखिम की राशि शामिल है

एक के बाद एक मामले को आने देने से जुड़ी दो मुख्य समस्याएं हैं:

  1. यह आपके कोड को केस स्टेटमेंट के आदेश पर निर्भर करता है। यदि आप कभी नहीं गिरते हैं, तो यह मामला नहीं है और यह जटिलता की एक डिग्री जोड़ता है जो अक्सर अवांछित होता है।

  2. यह स्पष्ट नहीं है कि एक मामले के लिए कोड में एक या अधिक बाद के मामलों के लिए कोड शामिल है।

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


4

यहाँ मेरे जीवन को सरल बनाने के लिए गिरने के माध्यम से एक त्वरित (संयुक्त रूप से अपूर्ण (लीप वर्ष की कोई विशेष हैंडलिंग नहीं) उदाहरण दिया गया है:

function get_julian_day (date) {
    int utc_date = date.getUTCDate();
    int utc_month = date.getUTCMonth();

    int julian_day = 0;

    switch (utc_month) {
        case 11: julian_day += 30;
        case 10: julian_day += 31;
        case 9:  julian_day += 30;
        case 8:  julian_day += 31;
        case 7:  julian_day += 31;
        case 6:  julian_day += 30;
        case 5:  julian_day += 31;
        case 4:  julian_day += 30;
        case 3:  julian_day += 31;
        case 2:  julian_day += 28;
        case 1:  julian_day += 31;
        default: break;
    }

    return julian_day + utc_date;
}

5
जबकि यह एक तरह का चतुर है, जिस समय को आप ऐसा करने से बचाते हैं, वह उस समय से बहुत अधिक होने वाला है जब अन्य लोगों को यह पता लगाने में समय लगता है कि यह क्या करता है। इसके अलावा, आप फॉल-थ्रू पहलू को हटाकर बेहतर प्रदर्शन प्राप्त कर सकते हैं अर्थात 31 + 28 + 31 हमेशा 90 होता है। यदि आप ऐसा करने जा रहे हैं, तो आप केवल मामलों में कुल योग डाल सकते हैं क्योंकि विचार करने के लिए केवल 11 हैं।
जिम्मीजम्स

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

2
मैं आपको वह अनुदान दूंगा, लेकिन एक निरंतर घोषणा में ऐसा करना बेहतर होगा जैसे कि FEB_START = 31; MAR_START = FEB_START + 28; आदि यह सुनिश्चित नहीं है कि यह किस भाषा में है, लेकिन कई में इसका संकलन समय पर किया जाएगा। यहाँ बड़ा मुद्दा यह है कि यह थोड़ा सा विरोध है। इतना नहीं कि यह एक बुरा विचार है, सिर्फ atypical है। जब तक वास्तव में बड़ा लाभ नहीं होता, तब तक आम मुहावरों के साथ रहना बेहतर होता है।
जिमीजैमस

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

3

यदि मुझे एक मामले से दूसरे मामले में जाने की आवश्यकता महसूस होती है (दुर्लभ, स्वीकार की जाती है), तो मैं बहुत स्पष्ट होना पसंद करता हूं और goto caseनिश्चित रूप से, यह मानता है कि आपकी भाषा इसका समर्थन करती है।

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

यह उन बग्स से बचने में भी मदद करता है जो तब हो सकते हैं जब केस स्टेटमेंट को फिर से व्यवस्थित किया जाता है।

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