Go में struct, slice और map की तुलना: पूर्ण विश्लेषण

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

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

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

Go में struct, slice और map की तुलना: शुरुआत से विशेषज्ञ तक

\n\n

क्या आपने कभी Go में कोड लिखा है जो दो struct, दो slices या दो maps की तुलना करने वाला था, और आपको कम्पाइलेशन एरर मिला: invalid operation: cannot compare? यदि हाँ — तो आप अकेले नहीं हैं। यह Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है (दसियों हज़ार व्यूज़!), जो अन्य भाषाओं से Go पर आए अनुभवी डेवलपर्स को भी हैरान कर देता है।

\n\n

इस लेख में हम हमेशा के लिए समझेंगे कि Go में कम्पाउंड डेटा प्रकारों की सही तरीके से तुलना कैसे करें. आप जानेंगे कि == हमेशा क्यों काम नहीं करता, कब reflect.DeepEqual का उपयोग करना चाहिए, और अपना कुशल तुलना फ़ंक्शन कैसे लिखें। चलिए शुरू करते हैं!

\n\n

== के माध्यम से सरल तुलना हमेशा क्यों काम नहीं करती?

\n\n

Go में, == ऑपरेटर केवल तुलनीय प्रकारों (comparable) के लिए काम करता है। इनमें शामिल हैं:

\n\n
    \n
  • बेसिक प्रकार: int, string, bool, float आदि।
  • \n
  • पॉइंटर्स (pointer)
  • \n
  • चैनल (channel)
  • \n
  • इंटरफ़ेस (यदि डायनामिक प्रकार तुलनीय हैं)
  • \n
  • स्ट्रक्चर, जिनके सभी फ़ील्ड तुलनीय हैं
  • \n
  • ऐरे (array), यदि ऐरे का एलिमेंट तुलनीय है
  • \n
\n\n

लेकिन slices (slice) और maps (map) सीधे == के माध्यम से तुलनीय नहीं हैं। ऐसा करने का प्रयास कम्पाइलेशन एरर देगा। क्यों? क्योंकि slice एक रेफरेंशियल प्रकार है, जिसमें डेटा पर पॉइंटर, लंबाई और क्षमता शामिल होती है। दो slices सामग्री में "बराबर" हो सकते हैं, लेकिन उनकी आंतरिक संरचनाएँ अलग हो सकती हैं।

\n\n
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 के साथ समानता।

\n\n

Go में struct की तुलना

\n\n

struct की तुलना सबसे पेचीदा मामला है। यदि आपके struct के सभी फ़ील्ड तुलनीय प्रकार हैं, तो == काम करता है!

\n\n
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\n
type 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।

\n\n

समाधान #1: reflect.DeepEqual — सार्वभौमिक, लेकिन धीमा

\n\n

किसी भी जटिल प्रकार की तुलना करने का सबसे आसान तरीका Go की मानक लाइब्रेरी से reflect.DeepEqual फ़ंक्शन का उपयोग करना है। यह रिकर्सिव रूप से struct, slice, map को पार करता है और उनकी सामग्री की तुलना करता है।

\n\n
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

<

ब्लॉग

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