मॉड्यूल पाठ (2/5)
तरीके: मूल्य बनाम सूचक रिसीवर
गो में एक विधि एक रिसीवर वाला एक फ़ंक्शन है: एक विशेष
func और विधि नाम के बीच घोषित पैरामीटर, जो बांधता है
एक प्रकार की विधि. कोई वर्ग नहीं हैं: विधियों को परिभाषित किया जा सकता है
वर्तमान पैकेज में घोषित कोई भी नामित प्रकार।
सिंटेक्स
type Person struct {
Name string
}
func (p Person) Greet() string {
return "ciao " + p.Name
}
p := Person{Name: "Ada"}
fmt.Println(p.Greet()) // "ciao Ada"रिसीवर p Person Greet को Person की एक विधि बनाता है। के अंदर
विधि, p किसी भी अन्य की तरह एक चर है।
वैल्यू रिसीवर बनाम पॉइंटर रिसीवर
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
return strings.ToUpper(p.Name)
}
// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
p.Name = n
}एक पॉइंटर रिसीवर के साथ आप रिसीवर को संशोधित और परिवर्तन कर सकते हैं विधि के बाहर दिखाई दे रहे हैं। एक मूल्य रिसीवर के साथ आप ऐसा नहीं कर सकते - आप करेंगे केवल स्थानीय प्रतिलिपि को संशोधित करें।
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name) // "Grace" — change is visibleपॉइंटर रिसीवर का उपयोग कब करें
प्राथमिकता के क्रम में व्यावहारिक नियम:
- आपको रिसीवर को संशोधित करना होगा → पॉइंटर रिसीवर। अनिवार्य।
- संरचना बड़ी है (दर्जनों फ़ील्ड, अंदर सरणियाँ) → सूचक महंगी प्रतियों से बचने के लिए रिसीवर।
- संगति: यदि प्रकार की कम से कम एक विधि में पॉइंटर रिसीवर है, तो उपयोग करें दूसरों के लिए भी एक सूचक रिसीवर। के लिए एक बहुत ही महत्वपूर्ण सम्मेलन इंटरफेस (मॉड्यूल 6)।
- छोटे, अपरिवर्तनीय, "मूल्य" प्रकार (समय.समय, सम्मिश्र संख्याएँ, छोटे structs) → मूल्य रिसीवर, अधिक पठनीय।
गैर-संरचना प्रकारों पर विधियाँ
आप अपने पैकेज में घोषित किसी भी NAMED प्रकार पर विधियों को परिभाषित कर सकते हैं:
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
t := Celsius(20)
fmt.Println(t.ToFahrenheit()) // 68आप उन्हें अन्य पैकेजों (जैसे int, string) के प्रकारों पर परिभाषित नहीं कर सकते: आपको अवश्य करना चाहिए
सबसे पहले एक स्थानीय नामित प्रकार बनाएं।
इसे अजमाएं
पर्सन में एक ग्रीट() स्ट्रिंग विधि (वैल्यू रिसीवर) जोड़ें जो 'ciao <Name>' लौटाता है।
संकेत दिखाएँ
विधि नाम से पहले कोष्ठक में रिसीवर।
3 प्रयासों के बाद समाधान उपलब्ध है
एक POINTER रिसीवर के साथ एक नाम बदलें (n स्ट्रिंग) विधि जोड़ें जो p.Name को बदलता है।
संकेत दिखाएँ
सूचक रिसीवर: `(पी *व्यक्ति)`।
3 प्रयासों के बाद समाधान उपलब्ध है
आपको पॉइंटर रिसीवर (p*T) का उपयोग कब करना चाहिए?
func (t ?T) M() { ... }संक्षिप्त
- विधि = रिसीवर के साथ कार्य करें:
func (r T) Name(...) ... { ... }। - मूल्य रिसीवर: एक प्रति पर काम करता है; पॉइंटर रिसीवर: मूल पर काम करता है।
- गो कॉल साइट पर स्वचालित रूप से
T↔*Tरूपांतरण करता है। - पॉइंटर रिसीवर जब: उत्परिवर्तन + बड़ी संरचना + प्रकार के अन्य तरीकों के साथ स्थिरता।
- कभी भी वैल्यू और पॉइंटर रिसीवर्स को एक ही प्रकार में न मिलाएं।
- वर्तमान पैकेज (गैर-संरचना सहित) में विधियाँ NAMED प्रकारों पर चलती हैं।