परिचय: Go 'enum' क्यों नहीं कहता?
\n\nअगर आप Python, Java या C# से Go में आए हैं, तो आपको शायद हल्का सा कल्चरल शॉक लगा होगा: Go में कोई enum कीवर्ड नहीं है। कोई बिल्ट-इन enumeration नहीं जो अपने आप नंबरिंग करे, कोई .name() या .valueOf() मेथड नहीं। बस आप, कंपाइलर और... कॉन्स्टेंट्स।
सवाल "What is an idiomatic way of representing enums in Go?" Stack Overflow के Golang सेक्शन में सबसे लोकप्रिय सवालों में से एक है (हजारों व्यूज)। और यह कोई संयोग नहीं है। हर नौसिखिया को देर-सबेर एक दीवार से टकराना पड़ता है: "मैं enum को Go-स्टाइल में कैसे बनाऊं?"।
\n\nइस लेख में हम सिर्फ जवाब नहीं देंगे। हम अंदर की बात भी देखेंगे: Go कॉन्स्टेंट्स को कैसे प्रोसेस करता है, iota क्या है, और कंपाइलर दो अलग-अलग int वैल्यू को अलग टाइप क्यों नहीं मानता। अंत में आप जानेंगे कि enum को सुरक्षित, सुविधाजनक और खूबसूरत कैसे बनाया जाए।
समस्या: साधारण कॉन्स्टेंट्स क्यों खराब हैं?
\n\nसबसे पहले जो दिमाग में आता है — कुछ कॉन्स्टेंट्स घोषित करना:
\n\nconst (\n StatusActive = 1\n StatusInactive = 2\n StatusPending = 3\n)\n\nयह काम करता है। लेकिन एक समस्या है: कोई भी फंक्शन जो int लेता है, वह 999 या -42 वैल्यू को भी स्वीकार कर लेगा। कंपाइलर कुछ नहीं कहेगा। यह enumeration नहीं है — यह सिर्फ नाम वाले नंबर हैं।
असली enum को यह करना चाहिए:
\n- \n
- स्वीकार्य मानों के सेट को सीमित करना; \n
- टाइप-सेफ होना (जहाँ
Statusकी उम्मीद हो, वहाँintनहीं भेजा जा सकता); \n - पढ़ने में आसान और आसानी से विस्तार योग्य होना। \n
Go इस समस्या को मुहावरेदार तरीके से हल करता है: कस्टम टाइप और iota के जरिए।
मुहावरेदार तरीका: टाइप + iota
\n\nयहाँ देखिए उसी Stack Overflow का कैनोनिकल जवाब कैसा दिखता है:
\n\ntype 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
अब जो फंक्शन Status लेता है, वह सामान्य int देने पर कंपाइल नहीं होगा:
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\niota क्यों, मैन्युअल नंबरिंग क्यों नहीं?
\n\nकल्पना करें कि आपने लिस्ट के बीच में एक नया स्टेटस जोड़ा। मैन्युअल नंबरिंग में आपको बाद के सभी मान बदलने पड़ते। iota यह अपने आप करता है। यह सिर्फ सुविधाजनक नहीं है — यह मुहावरेदार है।
अंदर की बात: Go enum को कैसे देखता है
\n\nआइए समझते हैं कि कंपाइलेशन के दौरान वास्तव में क्या होता है।
\n\n1. iota — यह runtime नहीं है
\n\niota प्रोग्राम के चलने के दौरान मौजूद नहीं होता। यह एक प्रीप्रोसेसर टूल है (अधिक सटीक रूप से, पैकेज कंपाइलर का हिस्सा)। कंपाइलेशन के दौरान सभी iota को विशिष्ट संख्याओं से बदल दिया जाता है। अंतिम बाइनरी में आपको सिर्फ 0, 1, 2 दिखेंगे।
इसे go tool compile से या असेंबली कोड देखकर जांचा जा सकता है:
// मूल कोड\nconst (\n A