Go में खाली स्लाइस: उदाहरणों के साथ सही इनिशियलाइज़ेशन

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

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

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

Go में खाली स्लाइस: शुरुआत से ही गलती कैसे न करें

\n\n

Go पर हर डेवलपर को देर-सबेर इस सवाल का सामना करना पड़ता है: "खाली स्लाइस को सही तरीके से कैसे इनिशियलाइज़ करें?"। यह एक साधारण काम लगता है, लेकिन सब कुछ इतना स्पष्ट नहीं है। Go के आधिकारिक FAQ और Stack Overflow पर इस विषय पर सैकड़ों टिप्पणियाँ और हज़ारों वोट हैं। क्यों?

\n\n

क्योंकि Go में खाली स्लाइस बनाने के दो मौलिक रूप से अलग-अलग तरीके हैं, और उनके बीच का चुनाव प्रदर्शन, कोड की पठनीयता और यहाँ तक कि सीरियलाइज़ेशन के व्यवहार को भी प्रभावित करता है। यदि आप Go में लिख रहे हैं और बिना किसी आश्चर्य के स्वच्छ, कुशल कोड लिखना चाहते हैं — तो यह लेख आपके लिए है।

\n\n

हम चर्चा करेंगे:

\n
    \n
  • var s []int और s := make([]int, 0) में क्या अंतर है
  • \n
  • nil-स्लाइस का उपयोग कब करें, और खाली स्लाइस का कब
  • \n
  • यह JSON, मेमोरी और प्रदर्शन को कैसे प्रभावित करता है
  • \n
  • Go के गुरु और मानक लाइब्रेरी के लेखक क्या कहते हैं
  • \n
\n\n

दो जुड़वाँ भाई: nil slice बनाम empty slice

\n\n

Go में, स्लाइस तीन फ़ील्ड की एक संरचना है: ऐरे का पॉइंटर, लंबाई और क्षमता। जब हम खाली स्लाइस कहते हैं, तो हमारा मतलब 0 लंबाई वाली स्लाइस से होता है। लेकिन हम इसे कैसे बनाते हैं, यह मायने रखता है।

\n\n

तरीका 1: var-घोषणा (nil slice)

\n\n
var s []int  // s == nil, len(s) == 0, cap(s) == 0
\n\n

यह nil-स्लाइस है। यह मेमोरी में किसी भी ऐरे की ओर इशारा नहीं करता। फिर भी, आप इस पर append कॉल कर सकते हैं — Go स्वचालित रूप से मेमोरी आवंटित करेगा।

\n\n

तरीका 2: make-इनिशियलाइज़ेशन (empty slice)

\n\n
s := make([]int, 0)  // s != nil, len(s) == 0, cap(s) == 0
\n\n

यह खाली स्लाइस है। यह पहले से ही एक शून्य ऐरे (Go रनटाइम में एक विशेष zerobase) की ओर इशारा करता है।

\n\n

पहली नज़र में अंतर ध्यान देने योग्य नहीं है। लेकिन आइए गहराई से देखें।

\n\n

कंसोल आउटपुट और JSON — पहला जाल

\n\n

इस कोड को चलाने का प्रयास करें:

\n\n
package main\n\nimport (\n    "encoding/json"\n    "fmt"\n)\n\nfunc main() {\n    var nilSlice []int\n    emptySlice := make([]int, 0)\n\n    fmt.Printf("nilSlice: %v, is nil: %v\\n", nilSlice, nilSlice == nil)\n    fmt.Printf("emptySlice: %v, is nil: %v\\n", emptySlice, emptySlice == nil)\n\n    // JSON-सीरियलाइज़ेशन\n    nilJSON, _ := json.Marshal(nilSlice)\n    emptyJSON, _ := json.Marshal(emptySlice)\n\n    fmt.Printf("nilSlice JSON: %s\\n", nilJSON)\n    fmt.Printf("emptySlice JSON: %s\\n", emptyJSON)\n}
\n\n

परिणाम आपको आश्चर्यचकित करेगा:

\n\n
nilSlice: [], is nil: true\nemptySlice: [], is nil: false\nnilSlice JSON: null\nemptySlice JSON: []
\n\n

यह रहा मुख्य आश्चर्य! JSON-सीरियलाइज़ेशन अलग-अलग व्यवहार करता है। यदि आपका API प्रतिक्रिया में [] की अपेक्षा करता है, और आप nil-स्लाइस भेजते हैं — तो क्लाइंट को null मिलेगा। और यह अनुबंधों को तोड़ता है।

\n\n

कई REST-क्लाइंट (विशेषकर JavaScript पर) सख्ती से जाँच करते हैं: यदि प्रतिक्रिया में एक ऐरे की अपेक्षा है, और null आता है — तो फ्रंटएंड पर त्रुटि हो सकती है या तर्क बाधित हो सकता है।

\n\n

प्रदर्शन: क्या कोई अंतर है?

\n\n

संक्षिप्त उत्तर: हाँ, लेकिन 99% मामलों में यह नगण्य है।

\n\n

जब आप make([]int, 0) का उपयोग करते हैं, तो Go तुरंत स्लाइस संरचना (64-बिट सिस्टम पर 24 बाइट्स) के लिए मेमोरी आवंटित करता है और इसे zerobase से जोड़ता है। var का उपयोग करते समय — आवंटन केवल पहले append पर होता है।

\n\n

यदि आप एक ऐसी स्लाइस बना रहे हैं जो संभवतः खाली रहेगी, तो nil-स्लाइस एक मेमोरी आवंटन बचाता है। यदि आप निश्चित रूप से जानते हैं कि आप तत्व जोड़ेंगे — तो क्षमता निर्दिष्ट करने वाला make बेहतर प्रदर्शन देगा:

\n\n
// यदि आप अनुमानित आकार जानते हैं — capacity निर्दिष्ट करें\ns := make([]int, 0, 100)  // क्षमता 100, लंबाई 0\nfor i := 0; i < 100; i++ {\n    s = append(s, i)  // बिना पुनः आवंटन के!\n}
\n\n

लेकिन अधिकांश अनुप्रयोग कार्यों के लिए, अंतर

ब्लॉग

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