मैं इस तथ्य से परिचित हूं कि, गो, इंटरफेस डेटा के बजाय कार्यक्षमता को परिभाषित करते हैं। आप एक इंटरफ़ेस में विधियों का एक सेट रखते हैं, लेकिन आप उस इंटरफ़ेस को लागू करने वाले किसी भी क्षेत्र को निर्दिष्ट करने में असमर्थ हैं।
उदाहरण के लिए:
// Interface
type Giver interface {
Give() int64
}
// One implementation
type FiveGiver struct {}
func (fg *FiveGiver) Give() int64 {
return 5
}
// Another implementation
type VarGiver struct {
number int64
}
func (vg *VarGiver) Give() int64 {
return vg.number
}
अब हम इंटरफ़ेस और इसके कार्यान्वयन का उपयोग कर सकते हैं:
// A function that uses the interface
func GetSomething(aGiver Giver) {
fmt.Println("The Giver gives: ", aGiver.Give())
}
// Bring it all together
func main() {
fg := &FiveGiver{}
vg := &VarGiver{3}
GetSomething(fg)
GetSomething(vg)
}
/*
Resulting output:
5
3
*/
अब, आप जो नहीं कर सकते , वह कुछ इस तरह है:
type Person interface {
Name string
Age int64
}
type Bob struct implements Person { // Not Go syntax!
...
}
func PrintName(aPerson Person) {
fmt.Println("Person's name is: ", aPerson.Name)
}
func main() {
b := &Bob{"Bob", 23}
PrintName(b)
}
हालांकि, इंटरफेस और एम्बेडेड संरचनाओं के साथ खेलने के बाद, मैंने एक फैशन के बाद, ऐसा करने का एक तरीका खोज लिया है:
type PersonProvider interface {
GetPerson() *Person
}
type Person struct {
Name string
Age int64
}
func (p *Person) GetPerson() *Person {
return p
}
type Bob struct {
FavoriteNumber int64
Person
}
एम्बेडेड संरचना के कारण, बॉब के पास सब कुछ है जो व्यक्ति के पास है। यह व्यक्तिप्रोफ़ाइडर इंटरफ़ेस को भी लागू करता है, इसलिए हम बॉब को उन फ़ंक्शंस में पारित कर सकते हैं जो उस इंटरफ़ेस का उपयोग करने के लिए डिज़ाइन किए गए हैं।
func DoBirthday(pp PersonProvider) {
pers := pp.GetPerson()
pers.Age += 1
}
func SayHi(pp PersonProvider) {
fmt.Printf("Hello, %v!\r", pp.GetPerson().Name)
}
func main() {
b := &Bob{
5,
Person{"Bob", 23},
}
DoBirthday(b)
SayHi(b)
fmt.Printf("You're %v years old now!", b.Age)
}
यहाँ एक Go Playground है जो उपरोक्त कोड को प्रदर्शित करता है।
इस पद्धति का उपयोग करके, मैं एक इंटरफ़ेस बना सकता हूं जो व्यवहार के बजाय डेटा को परिभाषित करता है, और जिसे किसी भी संरचना द्वारा केवल उस डेटा को एम्बेड करके कार्यान्वित किया जा सकता है। आप उन कार्यों को परिभाषित कर सकते हैं जो स्पष्ट रूप से उस एम्बेडेड डेटा के साथ बातचीत करते हैं और बाहरी संरचना की प्रकृति से अनजान हैं। और सब कुछ संकलन समय पर जांचा जाता है! (एक ही तरीका है कि आप गड़बड़ कर सकते हैं, जिसे मैं देख सकता हूं, एक कंक्रीट के बजाय इंटरफ़ेस PersonProvider
को एम्बेड करना होगा। यह रनटाइम पर संकलन और विफल हो जाएगा।)Bob
Person
अब, यहाँ मेरा प्रश्न है: यह एक साफ चाल है, या मुझे इसे अलग तरह से करना चाहिए?