Go में Enums: मुहावरेदार तरीका और अंदर का जादू

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: Go 'enum' क्यों नहीं कहता?

\n\n

अगर आप Python, Java या C# से Go में आए हैं, तो आपको शायद हल्का सा कल्चरल शॉक लगा होगा: Go में कोई enum कीवर्ड नहीं है। कोई बिल्ट-इन enumeration नहीं जो अपने आप नंबरिंग करे, कोई .name() या .valueOf() मेथड नहीं। बस आप, कंपाइलर और... कॉन्स्टेंट्स।

\n\n

सवाल "What is an idiomatic way of representing enums in Go?" Stack Overflow के Golang सेक्शन में सबसे लोकप्रिय सवालों में से एक है (हजारों व्यूज)। और यह कोई संयोग नहीं है। हर नौसिखिया को देर-सबेर एक दीवार से टकराना पड़ता है: "मैं enum को Go-स्टाइल में कैसे बनाऊं?"।

\n\n

इस लेख में हम सिर्फ जवाब नहीं देंगे। हम अंदर की बात भी देखेंगे: Go कॉन्स्टेंट्स को कैसे प्रोसेस करता है, iota क्या है, और कंपाइलर दो अलग-अलग int वैल्यू को अलग टाइप क्यों नहीं मानता। अंत में आप जानेंगे कि enum को सुरक्षित, सुविधाजनक और खूबसूरत कैसे बनाया जाए।

\n\n

समस्या: साधारण कॉन्स्टेंट्स क्यों खराब हैं?

\n\n

सबसे पहले जो दिमाग में आता है — कुछ कॉन्स्टेंट्स घोषित करना:

\n\n
const (\n    StatusActive   = 1\n    StatusInactive = 2\n    StatusPending  = 3\n)
\n\n

यह काम करता है। लेकिन एक समस्या है: कोई भी फंक्शन जो int लेता है, वह 999 या -42 वैल्यू को भी स्वीकार कर लेगा। कंपाइलर कुछ नहीं कहेगा। यह enumeration नहीं है — यह सिर्फ नाम वाले नंबर हैं।

\n\n

असली enum को यह करना चाहिए:

\n
    \n
  • स्वीकार्य मानों के सेट को सीमित करना;
  • \n
  • टाइप-सेफ होना (जहाँ Status की उम्मीद हो, वहाँ int नहीं भेजा जा सकता);
  • \n
  • पढ़ने में आसान और आसानी से विस्तार योग्य होना।
  • \n
\n\n

Go इस समस्या को मुहावरेदार तरीके से हल करता है: कस्टम टाइप और iota के जरिए।

\n\n

मुहावरेदार तरीका: टाइप + iota

\n\n

यहाँ देखिए उसी Stack Overflow का कैनोनिकल जवाब कैसा दिखता है:

\n\n
type Status int\n\nconst (\n    StatusActive   Status = iota // 0\n    StatusInactive               // 1\n    StatusPending                // 2\n    StatusDeleted                // 3\n)
\n\n

यहाँ क्या हुआ?

\n
    \n
  • type Status int — हमने एक नया नामित टाइप बनाया। हाँ, अंदर से यह int है, लेकिन कंपाइलर के लिए Status और int अलग चीजें हैं।
  • \n
  • iota — यह एक लगातार पूर्णांक जनरेटर है, जो सिर्फ const-ब्लॉक के अंदर काम करता है। हर नई लाइन वैल्यू को 1 से बढ़ा देती है।
  • \n
\n\n

अब जो फंक्शन Status लेता है, वह सामान्य int देने पर कंपाइल नहीं होगा:

\n\n
func Process(s Status) {\n    // ...\n}\n\nfunc main() {\n    Process(StatusActive) // OK\n    Process(1)            // कंपाइलेशन एरर! Cannot use 1 (type int) as type Status\n}
\n\n

यही है टाइप-सेफ्टी — enum के लिए कस्टम टाइप इस्तेमाल करने का पहला और सबसे बड़ा कारण।

\n\n

iota क्यों, मैन्युअल नंबरिंग क्यों नहीं?

\n\n

कल्पना करें कि आपने लिस्ट के बीच में एक नया स्टेटस जोड़ा। मैन्युअल नंबरिंग में आपको बाद के सभी मान बदलने पड़ते। iota यह अपने आप करता है। यह सिर्फ सुविधाजनक नहीं है — यह मुहावरेदार है।

\n\n

अंदर की बात: Go enum को कैसे देखता है

\n\n

आइए समझते हैं कि कंपाइलेशन के दौरान वास्तव में क्या होता है।

\n\n

1. iota — यह runtime नहीं है

\n\n

iota प्रोग्राम के चलने के दौरान मौजूद नहीं होता। यह एक प्रीप्रोसेसर टूल है (अधिक सटीक रूप से, पैकेज कंपाइलर का हिस्सा)। कंपाइलेशन के दौरान सभी iota को विशिष्ट संख्याओं से बदल दिया जाता है। अंतिम बाइनरी में आपको सिर्फ 0, 1, 2 दिखेंगे।

\n\n

इसे go tool compile से या असेंबली कोड देखकर जांचा जा सकता है:

\n\n
// मूल कोड\nconst (\n    A                

ब्लॉग

पुस्तक अनुशंसाएँ