मॉड्यूल पाठ (3/5)
रचना (एम्बेडिंग)
गो की कोई विरासत नहीं है। पुन: उपयोग का मुहावरेदार उत्तर है रचना, और विशेष रूप से एम्बेडिंग: एक प्रकार सहित फ़ील्ड नाम दिए बिना दूसरे के अंदर। के क्षेत्र और तरीके एम्बेडेड प्रकार को पदोन्नत किया जाता है, मानो वह सीधे पहुंच योग्य हो जाता है वे बाहरी प्रकार के थे।
संरचना एम्बेडिंग
type Animal struct {
Name string
}
func (a Animal) Greet() string {
return "ciao da " + a.Name
}
type Dog struct {
Animal // embedding — NO field name
Breed string
}
c := Dog{
Animal: Animal{Name: "Rex"},
Breed: "Pastore",
}
fmt.Println(c.Name) // "Rex" — promoted from Animal
fmt.Println(c.Greet()) // "ciao da Rex" — promoted method
fmt.Println(c.Breed) // own fieldएम्बेडेड फ़ील्ड अभी भी प्रकार के नाम से पहुंच योग्य है:
c.Animal.Name काम करता है और c.Name के समान है। इसकी जरूरत तब पड़ती है
टकराव होते हैं.
ओवरराइड (आंशिक): विधि "छायाांकन"
यदि बाहरी प्रकार प्रचारित के समान नाम के साथ एक विधि को परिभाषित करता है एक, इसकी विधि "जीतती है"। अंदर से आप हमेशा अंतर्निहित तक पहुंच सकते हैं प्रकार के नाम के माध्यम से एक:
func (c Dog) Greet() string {
return "BAU! " + c.Animal.Greet()
}यह बहुरूपी वंशानुक्रम नहीं है: यह केवल शाब्दिक नाम संकल्प है। बहुरूपता के लिए आप इंटरफ़ेस (मॉड्यूल 6) का उपयोग करते हैं।
एकाधिक एम्बेडिंग
आप कई प्रकार एम्बेड कर सकते हैं:
type Logger struct{ /*...*/ }
func (l Logger) Log(msg string) { /*...*/ }
type Timer struct{ /*...*/ }
func (t Timer) Now() time.Time { /*...*/ }
type Service struct {
Logger
Timer
Name string
}
s := Service{Name: "api"}
s.Log("start") // promoted from Logger
s.Now() // promoted from Timerयदि दो एम्बेडेड प्रकारों में एक ही नाम वाली एक विधि है, तो सीधी पहुंच
अस्पष्ट हो जाता है और संकलक को स्पष्ट रूप की आवश्यकता होती है
(s.Logger.Foo() या s.Timer.Foo())।
इंटरफ़ेस एम्बेडिंग
इंटरफ़ेस को "एम्बेडेड" भी किया जा सकता है (मॉड्यूल 6 देखें):
type ReadWriter interface {
io.Reader
io.Writer
}यह Reader और Writer के तरीकों के मिलन के बराबर है।
स्पष्ट रचना का उपयोग कब करें (एम्बेडिंग नहीं)
यदि आप एक नामित फ़ील्ड चाहते हैं और कोई ऑटो-प्रमोशन नहीं है, तो सादे का उपयोग करें रचना:
type Dog struct {
Anim Animal // NORMAL field, no promotion
Breed string
}
c.Anim.Name // you need the field nameएंबेडिंग एक आसान प्रतिनिधि उपकरण है, डिज़ाइन विकल्प नहीं स्पष्ट रूप से स्पष्ट रचना से बेहतर: जब आप वास्तव में चाहें तब इसका उपयोग करें आंतरिक प्रकार के एपीआई को बढ़ावा देने के लिए।
इसे अजमाएं
कुत्ते को परिभाषित करें जो एनिमल को एम्बेड करता है (एम्बेडिंग, कोई फ़ील्ड नाम नहीं) और एक ब्रीड स्ट्रिंग फ़ील्ड है।
संकेत दिखाएँ
एम्बेडिंग: TYPE को फ़ील्ड का नाम दिए बिना लिखें।
3 प्रयासों के बाद समाधान उपलब्ध है
एनिमल में एक ग्रीट() स्ट्रिंग विधि जोड़ें और इसे सीधे डॉग वेरिएबल (विधि प्रचार) पर कॉल करें।
संकेत दिखाएँ
एम्बेडिंग की बदौलत एनिमल पर परिभाषित विधि को डॉग में प्रचारित किया गया है।
3 प्रयासों के बाद समाधान उपलब्ध है
क्या गो शास्त्रीय विरासत का समर्थन करता है?
type B struct { /* extends A? */ }संक्षिप्त
- कोई विरासत नहीं: आप एम्बेडिंग के साथ रचना करते हैं।
- एंबेडिंग = संरचना में फ़ील्ड नाम के बिना प्रकार लिखना।
- एम्बेडेड प्रकार के फ़ील्ड और तरीकों को पदोन्नत किया जाता है।
- स्पष्ट पहुंच हमेशा उपलब्ध है:
outer.Inner.Field। - "लेक्सिकल" ओवरराइड: बाहरी प्रकार की विधि प्रचारित विधि को छाया देती है।
- एम्बेडिंग ≠ है-एक: बहुरूपता के लिए इंटरफ़ेस का उपयोग करें।