परिचय: Go डेवलपर के लिए सत्य का क्षण
\n\nयदि आपने कभी Go (Golang) में प्रोग्राम लिखा है और इंटरफ़ेस का उपयोग किया है, तो आपने निश्चित रूप से यह कंपाइलर संदेश देखा होगा:
\n\ncannot use x (variable of type *MyStruct) as type MyInterface value in assignment:\n*MyStruct does not implement MyInterface (method GetName has a pointer receiver)\n\nStack Overflow पर यह प्रश्न हजारों बार देखा जाता है। नए लोग असमंजस में पड़ जाते हैं, अनुभवी कंधे उचकाते हैं। लेकिन वास्तव में इस त्रुटि के पीछे एक सुंदर और महत्वपूर्ण अवधारणा है: Go भाषा में value receiver और pointer receiver के बीच अंतर।
\n\nइस लेख में हम Go कंपाइलर के 'हुड के नीचे' झांकेंगे, वास्तविक कोड उदाहरणों का विश्लेषण करेंगे और समझेंगे कि इस जाल से कैसे बचा जाए। आप न केवल यह जानेंगे कि त्रुटि क्यों होती है, बल्कि यह भी कि यह कैसे टाइप और इंटरफ़ेस सिस्टम से संबंधित है।
\n\n1. Go में इंटरफ़ेस: एक संक्षिप्त परिचय
\n\nत्रुटि में गोता लगाने से पहले, आइए याद करें कि Go इंटरफ़ेस कैसे काम करते हैं। Java या C++ के विपरीत, Go में इंटरफ़ेस विधियों का एक सेट है। यदि कोई प्रकार इंटरफ़ेस की सभी विधियों को लागू करता है, तो वह स्वचालित रूप से उस इंटरफ़ेस को संतुष्ट करता है (डक टाइपिंग)।
\n\nएक सरल इंटरफ़ेस का उदाहरण:
\n\ntype Speaker interface {\n Speak() string\n}\n\nअब एक स्ट्रक्चर और एक विधि परिभाषित करते हैं:
\n\ntype Dog struct {\n Name string\n}\n\n// Value receiver — विधि स्ट्रक्चर की एक प्रतिलिपि पर काम करती है\nfunc (d Dog) Speak() string {\n return "भौं! मैं " + d.Name\n}\n\nयहाँ, Dog Speaker को लागू करता है। यह Dog और *Dog दोनों के साथ काम करता है:
var s Speaker\ns = Dog{Name: "टॉमी"} // ✅ ठीक है\ns = &Dog{Name: "शेरू"} // ✅ ठीक है (Go स्वचालित रूप से डीरेफरेंस करता है)\n\nअब तक सब सरल है। अब विधि को pointer receiver में बदलते हैं:
\n\nfunc (d *Dog) Speak() string {\n return "भौं! मैं " + d.Name\n}\n\nऔर यहाँ से जादू शुरू होता है।
\n\n2. Pointer receiver बनाम Value receiver: क्या अंतर है?
\n\nGo में, विधियों के दो प्रकार के प्राप्तकर्ता (receivers) हो सकते हैं:
\n\n- \n
- Value receiver
(t Type)— विधि मान की एक प्रतिलिपि प्राप्त करती है। \n - Pointer receiver
(t *Type)— विधि मूल मान का एक पॉइंटर प्राप्त करती है। \n
यह क्यों महत्वपूर्ण है? क्योंकि प्रकार की विधियों का सेट इस बात पर निर्भर करता है कि किस receiver का उपयोग किया गया है।
\n\nसत्य तालिका:
\n\n- \n
- प्रकार
Tमें value receiver वाली सभी विधियाँ हैं (Tके लिए)। \n - प्रकार
*Tमें value receiver + pointer receiver वाली सभी विधियाँ हैं। \n
दूसरे शब्दों में: पॉइंटर को विधियों का एक 'बोनस' सेट मिलता है, जबकि मान में केवल वे विधियाँ होती हैं जो value receiver के साथ घोषित की गई हैं।
\n\nयह कोई बग नहीं, बल्कि Go डिज़ाइन की एक विशेषता है। कंपाइलर स्वचालित रूप से मान का पता नहीं ले सकता यदि वह एड्रेसेबल नहीं है (उदाहरण के लिए, किसी फ़ंक्शन का परिणाम या लिटरल)।
\n\n3. त्रुटि का विश्लेषण: «method has a pointer receiver»
\n\nअपने उदाहरण पर वापस आते हैं। यदि Speak() को *Dog के साथ घोषित किया गया है, तो:
var s Speaker\ns = Dog{Name: "टॉमी"} // ❌ त्रुटि\n// cannot use Dog{...} as Speaker...\n// method has a pointer receiver\n\nक्यों? क्योंकि Dog (पॉइंटर नहीं) के पास अपने सेट में Speak() विधि नहीं है। विधि केवल *Dog की है।
लेकिन यह काम करता है:
\n\ns = &Dog{Name: "टॉमी"} // ✅ ठीक है\n\nअब आइए वास्तविक कोड से एक अधिक व्यावहारिक उदाहरण देखें, जो अक्सर Stack Overflow पर देखा जाता है।
\n\nउदाहरण: डेटा के साथ इंटरफ़ेस और स्ट्रक्चर
\n\npackage main\n\nimport "fmt"\n\ntype User interface {\n GetID() int\n SetName(name string)\n}\n\ntype Admin struct {\n ID int\