Go में struct, slice और map की तुलना: शुरुआत से विशेषज्ञ तक
\n\nक्या आपने कभी Go में कोड लिखा है जो दो struct, दो slices या दो maps की तुलना करने वाला था, और आपको कम्पाइलेशन एरर मिला: invalid operation: cannot compare? यदि हाँ — तो आप अकेले नहीं हैं। यह Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है (दसियों हज़ार व्यूज़!), जो अन्य भाषाओं से Go पर आए अनुभवी डेवलपर्स को भी हैरान कर देता है।
इस लेख में हम हमेशा के लिए समझेंगे कि Go में कम्पाउंड डेटा प्रकारों की सही तरीके से तुलना कैसे करें. आप जानेंगे कि == हमेशा क्यों काम नहीं करता, कब reflect.DeepEqual का उपयोग करना चाहिए, और अपना कुशल तुलना फ़ंक्शन कैसे लिखें। चलिए शुरू करते हैं!
== के माध्यम से सरल तुलना हमेशा क्यों काम नहीं करती?
\n\nGo में, == ऑपरेटर केवल तुलनीय प्रकारों (comparable) के लिए काम करता है। इनमें शामिल हैं:
- \n
- बेसिक प्रकार:
int,string,bool,floatआदि। \n - पॉइंटर्स (
pointer) \n - चैनल (
channel) \n - इंटरफ़ेस (यदि डायनामिक प्रकार तुलनीय हैं) \n
- स्ट्रक्चर, जिनके सभी फ़ील्ड तुलनीय हैं \n
- ऐरे (
array), यदि ऐरे का एलिमेंट तुलनीय है \n
लेकिन slices (slice) और maps (map) सीधे == के माध्यम से तुलनीय नहीं हैं। ऐसा करने का प्रयास कम्पाइलेशन एरर देगा। क्यों? क्योंकि slice एक रेफरेंशियल प्रकार है, जिसमें डेटा पर पॉइंटर, लंबाई और क्षमता शामिल होती है। दो slices सामग्री में "बराबर" हो सकते हैं, लेकिन उनकी आंतरिक संरचनाएँ अलग हो सकती हैं।
package main\n\nimport "fmt"\n\nfunc main() {\n a := []int{1, 2, 3}\n b := []int{1, 2, 3}\n \n // कम्पाइलेशन एरर!\n // fmt.Println(a == b) \n \n fmt.Println("केवल nil के साथ काम करता है:")\n fmt.Println(a == nil) // false\n fmt.Println(b == nil) // false\n}\n\nयही बात maps पर भी लागू होती है। केवल एक चीज़ जिसे आप == के माध्यम से जाँच सकते हैं वह है nil के साथ समानता।
Go में struct की तुलना
\n\nstruct की तुलना सबसे पेचीदा मामला है। यदि आपके struct के सभी फ़ील्ड तुलनीय प्रकार हैं, तो == काम करता है!
type Person struct {\n Name string\n Age int\n}\n\nfunc main() {\n p1 := Person{"Alice", 30}\n p2 := Person{"Alice", 30}\n \n fmt.Println(p1 == p2) // true — काम करता है!\n}\n\nलेकिन समस्या तब आती है जब struct में slice या map हो:
\n\ntype PersonWithHobbies struct {\n Name string\n Age int\n Hobbies []string // slice — तुलनीय प्रकार नहीं\n}\n\nfunc main() {\n p1 := PersonWithHobbies{"Bob", 25, []string{"reading", "coding"}}\n p2 := PersonWithHobbies{"Bob", 25, []string{"reading", "coding"}}\n \n // कम्पाइलेशन एरर!\n // fmt.Println(p1 == p2)\n}\n\nइस मामले में, Go कम्पाइलर एक एरर देगा: struct containing []string cannot be compared।
समाधान #1: reflect.DeepEqual — सार्वभौमिक, लेकिन धीमा
\n\nकिसी भी जटिल प्रकार की तुलना करने का सबसे आसान तरीका Go की मानक लाइब्रेरी से reflect.DeepEqual फ़ंक्शन का उपयोग करना है। यह रिकर्सिव रूप से struct, slice, map को पार करता है और उनकी सामग्री की तुलना करता है।
import (\n "fmt"\n "reflect"\n)\n\nfunc main() {\n // slices की तुलना\n a := []int{1, 2, 3}\n b := []int{1, 2, 3}\n fmt.Println(reflect.DeepEqual(a, b)) // true\n \n // maps की तुलना\n m1 := map[string]int{"a": 1, "b": 2}\n m2 := map[string]int{"a": 1, "b": 2}\n fmt.Println(reflect.DeepEqual(m1, m2)) // true\n \n // गैर-तुलनीय फ़ील्ड वाले struct की तुलना\n p1 := PersonWithHobbies{"Bob", 25, []string{"reading"}}\n p2 := PersonWithHobbies{"Bob", 25, []string{"reading"}}\n fmt.Println(reflect.DeepEqual(p1, p2)) // true\n}\n\n<