क्या अशक्त प्रकार जादुई संख्या के लिए बेहतर हैं?


22

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

कौन सा प्रतिनिधित्व बेहतर है? दोनों को मूल्य अर्थ "कोई नहीं" के लिए एक स्थिति की जांच की आवश्यकता होती है, लेकिन मेरा मानना ​​है कि एक अशक्त प्रकार इरादे को थोड़ा बेहतर बताता है।


6
यदि एक नंबर का उपयोग किया जाता है, तो इसे निरंतर में रखें, सीधे कोड में नहीं।
रेनाटो दिनानी

@ RenatoDinhaniConceição जो एक सामान्य नियम नहीं हो सकता। अन्यथा आप सब कुछ सॉफ्टकोडिंग खत्म कर देते हैं।
साइमन बर्गोट

जवाबों:


24

विचार करें:

  • भाषा,

  • फ्रेमवर्क,

  • प्रसंग।

1. भाषा

Using का उपयोग करना अधिकतम के लिए एक समाधान हो सकता है।

  • उदाहरण के लिए, जावास्क्रिप्ट में एक अनन्तता है। C # does¹।

  • उदाहरण के लिए, एडा की सीमाएँ हैं। सी # नहीं है।

C # में, है int.MaxValue, लेकिन आप इसे अपने मामले में उपयोग नहीं कर सकते। int.MaxValueअधिकतम पूर्णांक है, 2,147,483,647। यदि आपके कोड में, आपके पास किसी चीज़ का अधिकतम मूल्य है, जैसे किसी चीज़ के विस्फोट से पहले अधिकतम स्वीकृत दबाव, तो 2,147,483,647 का उपयोग करने का कोई मतलब नहीं है।

2. ढाँचा

.NET फ्रेमवर्क इस बिंदु पर असंगत है, और इसके जादुई मूल्यों के उपयोग की आलोचना की जा सकती है।

उदाहरण के लिए, "Hello".IndexOf("Z")एक जादुई मूल्य लौटाता है -1। यह हो सकता है आसान बना देता है (यह करता है?) परिणाम में हेरफेर करने के:

int position = "Hello".IndexOf("Z");
if (position > 0)
{
    DoSomething(position);
}

कस्टम संरचना का उपयोग करने के बजाय:

SearchOccurrence occurrence = "Hello".IndexOf("Z");
if (occurrence.IsFound)
{
    DoSomething(occurrence.StartOffset);
}

लेकिन सहज नहीं है। क्यों -1और क्या नहीं -123? एक शुरुआत भी गलती से सोच सकता है कि 0"नहीं मिला" या केवल गलत अर्थ है (position >= 0)

3. प्रसंग

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

class Timeout
{
    // A value indicating whether there is a timeout.
    public bool IsTimeoutEnabled { get; set; }

    // The duration of the timeout, in milliseconds.
    public int Duration { get; set; }
}
  • क्या मैं Duration0 पर सेट कर सकता हूँ अगर IsTimeoutEnabledयह सच है?
  • अगर IsTimeoutEnabledझूठा है, तो क्या होगा अगर मैं Duration100 पर सेट हो जाऊं?

इससे कई गलतियाँ हो सकती हैं। निम्नलिखित कोड की कल्पना करें:

this.currentOperation.Timeout = new Timeout
{
    // Set the timeout to 200 ms.; we don't want this operation to be longer than that.
    Duration = 200,
};

this.currentOperation.Run();

ऑपरेशन दस सेकंड के लिए चलता है। क्या आप देख सकते हैं कि Timeoutकक्षा के प्रलेखन को पढ़े बिना इस कोड में क्या गलत है ?

निष्कर्ष

  • nullअच्छी तरह से विचार व्यक्त करता है कि मूल्य यहाँ नहीं है। यह प्रदान नहीं किया गया है। उपलब्ध नहीं है। यह न तो एक संख्या है, न ही एक शून्य / खाली स्ट्रिंग या जो भी। अधिकतम या न्यूनतम मूल्यों के लिए इसका उपयोग न करें।

  • int.MaxValueभाषा से दृढ़ता से संबंधित है। कक्षा int.MaxValueकी अधिकतम गति सीमा Vehicleया विमान, आदि के लिए अधिकतम स्वीकार्य गति का उपयोग न करें ।

  • -1अपने कोड में जादू के मूल्यों से बचें । वे भ्रामक हैं और कोड में गलतियों को जन्म देते हैं।

  • अपना खुद का वर्ग बनाएं जो न्यूनतम / अधिकतम मूल्यों के साथ और अधिक सीधा होगा। उदाहरण के लिए VehicleSpeedहो सकता है VehicleSpeed.MaxValue

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

  • दृष्टिकोण मिश्रण मत भूलना। उदाहरण के लिए:

    class DnsQuery
    {
        public const int NoTimeout = 0;
    
        public int Timeout { get; set; }
    }
    
    this.query.Timeout = 0; // For people who are familiar with timeouts set to zero.
    // or
    this.query.Timeout = DnsQuery.NoTimeout; // For other people.
    

Your आप अपना खुद का प्रकार बना सकते हैं जिसमें अनंत शामिल हैं। यहाँ, मैं intकेवल देशी प्रकार के बारे में बात कर रहा हूँ ।


1
"किसी ऐसी चीज का उपयोग करना जो दशकों से सभी के लिए सुसंगत होने के लिए इस्तेमाल किया गया है, यह एक बुरा विचार नहीं है" / "किसी भी पिछले दिशानिर्देश का पालन न करें और यदि किसी विशिष्ट क्षेत्र में दशकों से इसका सामान्य सम्मेलन हो, तो इसका उपयोग करें। अधिकांश लोग इस क्षेत्र में कोड लिख रहे हैं। " - कहीं एक टाइपो है, मुझे लगता है?
डेवॉर्ड

1
@ मैं यह मानता हूं कि मेनमा उन दिशानिर्देशों का जिक्र कर रहा है जो उसने खुद उस एक के ऊपर दिए थे।
जोशुआ ड्रेक

1
मैं इंडेक्सऑफ उदाहरण पर असहमत हूं, क्योंकि -1 स्ट्रिंग के बाहर है, जो कि जेड सबसे निश्चित रूप से है।
जोशुआ ड्रेक

5
"उदाहरण के लिए, जावास्क्रिप्ट में एक अनन्तता है। C # नहीं।" - हुह?
ब्लूराजा - डैनी पफ्लुगुएफ़ट

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

12

नल किसी जादुई नंबर से बेहतर नहीं है।

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

if (timeout == 4298435) ... // bad.
if (timeout == null) ... // bad.
if (timeout == NEVER_TIME_OUT) ... // yay! puppies and unicorns!

2
ठीक है, शायद यह भाषा पर अधिक निर्भर करता है, लेकिन सी # में, आप संभवतः करेंगे: यदि (समयबाह्य.सालव्यू) के बजाय अशक्त की तुलना में सीधे।
मैट एच

2
Null मैजिक नंबर से भी बदतर नहीं है। मैजिक नंबरों के साथ, आप कभी नहीं जानते कि मैजिक नंबर क्या है ... यह 0, -1, या कुछ और हो सकता है। null सिर्फ null है।
मार्को-फिसेट

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

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

1
@CodeInChaos: मुझे पता है कि आप दोनों कर सकते हैं, लेकिन मुझे HasValue पसंद है। मैं वास्तव में सामान्य रूप से अशक्त का बहुत बड़ा प्रशंसक नहीं हूं, लेकिन HasValue का उपयोग करने वाले अशक्त प्रकार एक विकल्प / शायद मेरे लिए थोड़ा करीब महसूस करते हैं, जिसका मैं प्रशंसक हूं।
मैट एच

10

MAGIC_NUMBERजहाँ भी संभव हो कोड को हमेशा बचना चाहिए। nullआशय की बहुत स्पष्ट अभिव्यक्ति है।


6

C # में, कई CLR वर्गों में एक स्थिर Emptyसदस्य है:

  • System.String.Empty
  • System.EventArgs.Empty
  • System.Guid.Empty
  • System.Drawing.Rectangle.Empty
  • System.Windows.Size.Empty

यह आपको याद रखने के लिए रखता है कि क्या किसी खाली वस्तु का निर्माण करने के लिए जादू के मूल्य का उपयोग करना है या अशक्त का उपयोग करना है।

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


3

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

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


3

इस मामले में, मुझे लगता है कि एक अशक्त प्रकार पूर्ण समझ में आता है।

अशक्त का अर्थ है मूल्य का अभाव। यह 0 के मान वाली संख्या की तुलना में एक अलग तरह की अवधारणा है।

यदि आप यह कहना चाहते हैं कि "यदि मैं आपको कोई मूल्य नहीं देता हूं, तो अधिकतम का उपयोग करें" तो शून्य में गुजरना यह व्यक्त करने का सटीक सही तरीका है।


1

अशक्त: सामान्य त्रुटि मान, अनिर्दिष्ट, शून्य, या मूल्य की अनुपस्थिति।

शून्य: एक वास्तविक, लेकिन जरूरी नहीं कि तार्किक या सहज मूल्य (इस संदर्भ में)। प्रारंभ में एक सामान्य मूल्य भी।

आपकी समस्या के संदर्भ में, timeoutInMillisecondsसंपत्ति वैकल्पिक है और इसमें कोई उल्लेख नहीं है कि इस दृष्टिकोण का ओवरहेड इसे विकल्प के रूप में अयोग्य घोषित करेगा।

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


0

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

पर्यावरण / भाषा के आधार पर अशक्त इस्तेमाल किया जा सकता है

  • बस 0 हो
  • कानूनी मूल्य नहीं हो सकता है
  • तीन तरह के तर्क के कारण अप्रत्याशित परिणाम उत्पन्न हो सकते हैं

MagicNumber हमेशा ऐसा ही व्यवहार करता है।


0

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


-1

नल एक जादुई नंबर का एकमात्र विकल्प नहीं है।

public static int NO_TIMEOUT = 0;  // javaish

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

Scala (उदाहरण के लिए) विकल्प वर्ग में एक अच्छा विकल्प है। विकल्प वर्ग में दो मानों में से एक है, कुछ - जो उस मूल्य को लपेटता है जिसे आप वास्तव में चाहते हैं और कोई नहीं - जिसका कोई मूल्य नहीं है।

यह किसी भी डेवलपर के लिए स्पष्ट करता है कि मूल्य नहीं हो सकता है और आपके पास इसके लिए बेहतर कोड था। खैर, इसे वैसे भी स्पष्ट करना चाहिए।

और सभी जादू नंबर एक समस्या नहीं हैं। संदर्भ 0, 1, 1024 आदि के आधार पर सभी स्पष्ट हो सकते हैं। 347? हाँ, कि आप से बचना चाहिए। :-)


4
-1: "अशक्त बुराई है" को उचित ठहराएं।
डेवॉर्ड

4
एक संख्या के लिए एक उपनाम को परिभाषित करना इस तथ्य को नहीं बदलता है कि यह अभी भी एक जादू की संख्या है।
17 की 26

ठीक है, शायद मेरे पास जादू की संख्या की एक अलग परिभाषा है। कृपया en.wikipedia.org/wiki/…
जॉन स्ट्रायर

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