make() बनाम new() Go में: 2025 में क्या चुनें? स्पष्ट गाइड

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

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

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

Make या New? Go डेवलपर का शाश्वत प्रश्न

\n\n

आप एक सप्ताह या एक वर्ष से Go में कोड लिख रहे हैं, लेकिन फिर भी कभी-कभी make() या new() चुनने से पहले एक पल के लिए रुक जाते हैं? यह सामान्य है। Stack Overflow पर "Why would I make() or new()?" प्रश्न ने दसियों हज़ार बार देखा गया है, और यह 2025 में भी प्रासंगिक बना हुआ है। क्यों? क्योंकि स्पष्ट सादगी के पीछे Go में मेमोरी प्रबंधन के दर्शन में एक मौलिक अंतर छिपा है।

\n\n

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

\n\n

संक्षिप्त उत्तर (उन लोगों के लिए जो जल्दी में हैं)

\n\n

यदि आपको स्लाइस (slice), मैप (map) या चैनल (channel) के लिए मेमोरी आवंटित करने की आवश्यकता है — तो make() का उपयोग करें। अन्य सभी मामलों में — new() या लिटरल &Type{} का उपयोग करें। लेकिन शैतान, हमेशा की तरह, विवरण में है।

\n\n

new() क्या है और यह कैसे काम करता है

\n\n

फ़ंक्शन new(T) — Go का एक बिल्ट-इन फ़ंक्शन है, जो प्रकार T के लिए मेमोरी आवंटित करता है, इसे शून्य करता है (zero value) और इस मेमोरी पर एक पॉइंटर लौटाता है: *T।

\n\n

सीधे शब्दों में कहें: new() आपको एक खाली लेकिन मान्य ऑब्जेक्ट देता है। आपको एक पॉइंटर मिलता है, लेकिन ऑब्जेक्ट स्वयं अभी पूरी तरह से उपयोग के लिए तैयार नहीं है, यदि इसे आंतरिक संरचनाओं के आरंभीकरण की आवश्यकता है।

\n\n
package main\n\nimport "fmt"\n\ntype Person struct {\n    Name string\n    Age  int\n}\n\nfunc main() {\n    p := new(Person)\n    fmt.Println(p)  // आउटपुट: &{ 0}\n    fmt.Println(p.Name == "") // true\n}\n
\n\n

यहाँ new(Person) ने स्ट्रक्चर के लिए मेमोरी आवंटित की, फ़ील्ड को शून्य किया (खाली स्ट्रिंग और 0) और पॉइंटर लौटाया। सब कुछ सही है।

\n\n

make() क्या है और इसकी सुपरपावर

\n\n

make() — भी एक बिल्ट-इन फ़ंक्शन है, लेकिन यह केवल तीन प्रकारों के साथ काम करता है: स्लाइस, मैप और चैनल। केवल ये क्यों? क्योंकि इन प्रकारों की एक आंतरिक संरचना (हेडर) होती है जिसे केवल शून्य करने के बजाय आरंभ करने की आवश्यकता होती है।

\n\n

make() पॉइंटर नहीं लौटाता। यह आवश्यक प्रकार का एक आरंभीकृत मान लौटाता है (पॉइंटर नहीं!)।

\n\n
// स्लाइस: लंबाई 5, क्षमता 10\ns := make([]int, 5, 10)\nfmt.Println(len(s), cap(s)) // 5 10\n\n// मैप: तत्वों को सम्मिलित करने के लिए तैयार\nm := make(map[string]int)\nm["key"] = 42\nfmt.Println(m) // map[key:42]\n\n// चैनल: 3 संदेशों के लिए बफ़र किया गया\nch := make(chan int, 3)\nch <- 1\nfmt.Println(<-ch) // 1\n
\n\n

ध्यान दें: यदि आप m := new(map[string]int) लिखने का प्रयास करते हैं, तो आपको nil-मैप पर एक पॉइंटर मिलेगा। ऐसे मैप में एक तत्व सम्मिलित करने से पैनिक (panic) हो जाएगा।

\n\n

new() स्लाइस, मैप और चैनल के लिए क्यों काम नहीं करता?

\n\n

आइए स्लाइस के उदाहरण पर देखें। Go में स्लाइस तीन फ़ील्ड की एक संरचना है: ऐरे पर पॉइंटर, लंबाई और क्षमता। new([]int) इस संरचना के लिए मेमोरी आवंटित करेगा और इसे शून्य करेगा। पॉइंटर nil होगा, लंबाई और क्षमता 0 होगी। आपको &[] मिलेगा — एक nil-स्लाइस पर पॉइंटर। क्या यह इंडेक्स द्वारा असाइनमेंट पर टूट जाएगा? नहीं, यह क्रैश हो जाएगा।

\n\n

make([]int, 3) तीन काम करता है:

\n
    \n
  • हुड के नीचे 3 तत्वों (या अधिक, यदि क्षमता निर्दिष्ट है) की एक वास्तविक ऐरे आवंटित करता है।
  • \n
  • स्लाइस हेडर (pointer, length, capacity) को आरंभ करता है।
  • \n
  • उपयोग के लिए तैयार स्लाइस लौटाता है।
  • \n
\n\n

मैप के साथ भी ऐसा ही: make(map[string]int) एक हैश टेबल बनाता है और बकेट के लिए मेमोरी आवंटित करता है। new(map[string]int) केवल nil-मैप देता है।

\n\n

2025 में new() का उपयोग कब करें?

\n\n

Go समुदाय में आधुनिक अभ्यास यह है: new() का उपयोग शायद ही कभी किया जाता है। अक्सर, डेवलपर पता लेने के साथ लिटरल पसंद करते हैं: &Type{}। यह अधिक पठनीय है और तुरंत फ़ील्ड सेट करने की अनुमति देता है।

ब्लॉग

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