गो में जेनेरिक्स: कैसे सामान्यीकृत प्रोग्रामिंग खेल के नियम बदल रही है

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

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

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

यह सब Go 1.18 से शुरू हुआ: जेनेरिक्स सिर्फ एक फैशनेबल फीचर क्यों नहीं है?

\n\n

लंबे समय तक, Go समुदाय को भाषा की सरलता पर गर्व था। सामान्यीकृत प्रोग्रामिंग (generics) की अनुपस्थिति को एक सचेत विकल्प माना जाता था: "हमें जटिल टेम्पलेट की आवश्यकता नहीं है, हम समझने योग्य कोड लिखते हैं"। लेकिन वास्तविकता ने अपना असर दिखाया। डेवलपर्स int, string और float64 के लिए फंक्शन कॉपी-पेस्ट करते-करते थक गए थे — या interface{} का उपयोग करके टाइप कास्टिंग करते थे, जिससे कंपाइलेशन के समय सुरक्षा खत्म हो जाती थी।

\n\n

Go 1.18 (2022) का आगमन एक क्रांति थी। जेनेरिक्स (generics) ने भाषा में टाइप पैरामीटर (type parameters) और प्रतिबंध (constraints) जोड़े। अब Go प्रोग्रामर प्रदर्शन और सख्त टाइपिंग से समझौता किए बिना सामान्यीकृत डेटा संरचनाएं और एल्गोरिदम लिख सकते हैं।

\n\n

इस लेख में pythonlib.ru पर, हम समझेंगे कि Go में generics कैसे काम करते हैं, वास्तविक कोड उदाहरण देखेंगे और जानेंगे कि उनका उपयोग कब करना चाहिए और कब नहीं। चलिए शुरू करते हैं!

\n\n

सरल शब्दों में Go में generics क्या है?

\n\n

कल्पना करें कि आप एक फंक्शन लिख रहे हैं जो एक स्लाइस में न्यूनतम तत्व ढूंढता है। जेनेरिक्स के बिना, आपको तीन संस्करण बनाने होंगे: int, float64 और string के लिए। या interface{} का उपयोग करके टाइप कास्टिंग करनी होगी — धीमी और असुरक्षित।

\n\n

Generics आपको एक फंक्शन लिखने की अनुमति देता है जो किसी भी प्रकार के साथ काम करता है, बशर्ते वह कुछ शर्तों को पूरा करता हो। सिंटैक्स सरल है: फंक्शन के नाम के बाद वर्गाकार कोष्ठक में टाइप पैरामीटर निर्दिष्ट किए जाते हैं।

\n\n

सिंटैक्स: वर्गाकार कोष्ठक और शब्द any

\n\n
package main\n\nimport "fmt"\n\n// Min — न्यूनतम खोजने के लिए सामान्यीकृत फंक्शन\nfunc Min[T any](a, b T) T {\n    // त्रुटि: any के लिए < ऑपरेटर परिभाषित नहीं है\n    // if a < b {\n    //     return a\n    // }\n    return b\n}
\n\n

उपरोक्त कोड संकलित नहीं होगा क्योंकि any एक खाली इंटरफ़ेस है (interface{} का पर्याय)। कंपाइलर नहीं जानता कि क्या प्रकार < ऑपरेटर का समर्थन करता है। प्रतिबंध (constraint) जोड़ने की आवश्यकता है।

\n\n

टाइप प्रतिबंध: constraints

\n\n

Go में, प्रतिबंध इंटरफ़ेस के माध्यम से निर्दिष्ट किए जाते हैं। आप पैकेज golang.org/x/exp/constraints से अंतर्निहित प्रतिबंधों का उपयोग कर सकते हैं या अपने स्वयं के लिख सकते हैं।

\n\n
import (\n    "fmt"\n    "golang.org/x/exp/constraints"\n)\n\n// Min किसी भी क्रमबद्ध प्रकार के साथ काम करता है\nfunc Min[T constraints.Ordered](a, b T) T {\n    if a < b {\n        return a\n    }\n    return b\n}\n\nfunc main() {\n    fmt.Println(Min(10, 20))       // 10\n    fmt.Println(Min(3.14, 2.71))   // 2.71\n    fmt.Println(Min("apple", "banana")) // "apple"\n}
\n\n

ध्यान दें: constraints.Ordered में वे सभी प्रकार शामिल हैं जिनके लिए ऑपरेटर <, <=, >, >= परिभाषित हैं — ये int, float, string हैं।

\n\n

व्यावहारिक उदाहरण: सरल से जटिल तक

\n\n

आइए देखें कि Go में generics वास्तविक कोड लिखने को कैसे सरल बनाते हैं।

\n\n

1. सामान्यीकृत स्टैक (Stack)

\n\n

जेनेरिक्स के बिना, आपको []interface{} स्टोर करना होगा और type assertion करना होगा। Generics के साथ — सुरुचिपूर्ण और सुरक्षित।

\n\n
package main\n\nimport "fmt"\n\n// Stack — सामान्यीकृत डेटा संरचना\ntype Stack[T any] struct {\n    items []T\n}\n\nfunc (s *Stack[T]) Push(item T) {\n    s.items = append(s.items, item)\n}\n\nfunc (s *Stack[T]) Pop() (T, bool) {\n    if len(s.items) == 0 {\n        var zero T\n        return zero, false\n    }\n    item := s.items[len(s.items)-1]\n    s.items = s.items[:len(s.items)-1]\n    return item, true\n}\n\nfunc main() {\n    intStack := Stack[int]{}\n    intStack.Push(1)\n    intStack.Push(2)\n    val, ok := intStack.Pop()\n    fmt.Println(val, ok) // 2 true\n\n    strStack := Stack[string]{}\n    strStack.Push("hello")\n                

ब्लॉग

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