2016-10-25 10 views
5

तो मैं इस उदाहरण यहाँ के साथ आवंटित: Go PlaygroundGolang: प्रकार एक और struct

package main 

import (
    "fmt" 
) 

type Circle struct{} 

func (c Circle) Something() { 
    fmt.Println("something") 
} 

type Rectangle struct { 
    Circle 
} 

func (a Rectangle) SomethingElse() { 
    fmt.Println("SomethingElse") 
} 

type Form Rectangle 

func main() { 
    c := Form{} 
    c.Circle.Something() 
    c.SomethingElse() 
} 

मुझे समझ नहीं आता क्यों मुझे एम्बेडेड Circle से Something कॉल कर सकते हैं, लेकिन भीतर Rectangle से Somethingelse कॉल नहीं कर सकते Form प्रकार। साथ ही मुझे समझ में नहीं आता कि जब मैं Form में किसी अन्य प्रकार का एक प्रकार घोषित करता हूं तो मुझे क्या लाभ होता है।

उत्तर

8

यह:

type Form Rectangle 

एक नईForm नामित प्रकार बनाता है, Rectangle अपने अंतर्निहित प्रकार के रूप में हो रही है।

इसका मतलब है कि Rectangle (जो एक संरचना है) के क्षेत्र Form के लिए भी परिभाषित किए जाएंगे।

लेकिन विधियां एक विशिष्ट प्रकार से बंधी हुई हैं। जब आप एक नया प्रकार (Form) बनाते हैं, तो उस नए प्रकार में इसके अंतर्निहित प्रकार की कोई भी विधि नहीं होगी, इसलिए आप c.SomethingElse() को SomethingElse() पर कॉल नहीं कर सकते हैं Rectangle प्रकार का एक तरीका है।

c.Circle.Something() काम करता है, क्योंकि c.Circle प्रकार Circle का एक क्षेत्र है, और Something()Circle प्रकार का एक तरीका है।

यदि आप Rectangle.SomethingElse() विधि को कॉल करना चाहते हैं, तो Rectangle (रिसीवर प्रकार Rectangle) का मान आवश्यक है। चूंकि Form के अंतर्निहित प्रकार Rectangle है, तो आप बस प्रकार Rectangle का एक मान प्रकार Form के एक मूल्य से एक सरल प्रकार conversion का उपयोग कर प्राप्त कर सकते हैं:

Rectangle(c).SomethingElse() // This works 

एक नए प्रकार बनाने के लाभ है कि ताकि आप बना सकते हैं/इसके लिए अपनी खुद की विधियां जोड़ें। एक आम उदाहरण sort.Interface इंटरफ़ेस को कार्यान्वित कर रहा है। मान लें कि आपके पास कुछ का टुकड़ा है, उदा। []Rectangle, या किसी प्रकार का एक टुकड़ा जिस पर आपका कोई नियंत्रण नहीं है (क्योंकि यह किसी अन्य पैकेज का हिस्सा है - और किसी प्रकार के तरीकों को केवल उसी पैकेज में परिभाषित किया जा सकता है)। आप इस टुकड़ा क्रमबद्ध करना चाहते हैं, तो आप एक नए प्रकार है जिसके लिए आप तरीकों को परिभाषित कर सकते, sort.Interface के तरीकों, उदा .:

type SortRectangle []Rectangle 

func (s SortRectangle) Len() int   { return len(s) } 
func (s SortRectangle) Less(i, j int) bool { return s[i] <some-logic> s[j] } 
func (s SortRectangle) Swap(i, j int)  { s[i], s[j] = s[j], s[i] } 

sort.Sort() समारोह किसी भी मान कि sort.Interface लागू सॉर्ट करने के लिए सक्षम है बनाएँ। []Rectangle नहीं है, लेकिन हमने अभी एक नया प्रकार SortRectangle बनाया है जो करता है।और यदि हमारे पास []Rectangle प्रकार का मान है, तो हम इसे SortRectangle में परिवर्तित कर सकते हैं क्योंकि पूर्व उत्तरार्द्ध का अंतर्निहित प्रकार है, और रूपांतरण करके, हमारे पास SortRectangle प्रकार का मान है जिसे sort.Sort() पर भेजा जा सकता है यह हल कर दिया है:

rs := []Rectangle{} 
// Sort rs: 
sort.Sort(SortRectangle(rs)) 

ध्यान दें कि ऊपर SortRectangle(rs) ऐसे रूपांतरण केवल क्रम प्रकार की जानकारी बदल जाता है, यह rs की स्मृति प्रतिनिधित्व नहीं बदलता है, तो यह pefectly सुरक्षित और कुशल है।

यदि आप नए प्रकार को "पुराने" प्रकार के तरीकों के बारे में चाहते हैं, तो एम्बेडिंग का उपयोग करें। ऐनार-जी का जवाब देखें। प्रकार Rectangle एक विधि Something() है, क्योंकि Something()Circle की एक विधि है: वास्तव में, आप पहले से ही इस Rectangle में Circle एम्बेड करके किया

Rectangle{}.Something() // Prints "something" 
+0

महान स्पष्टीकरण के लिए Thx! – simplebird

1

पूरे (और केवल) type Form Rectangle करने के लिए कारण एक परिभाषित करने के लिए है नयाविभिन्न विधियों के साथ टाइप करें। आपके उदाहरण में: कोई विधि नहीं। c एक प्रपत्र है और इसमें कोई तरीका नहीं है, यह केवल raison d'être SomethingElse() विधि वाला है।

लेकिन एक Form अभी भी एक सर्किल जो c.Circle के रूप में पहुँचा जा सकता है और जो एक Circle है, इसलिए यह obviousely विधि Something() है एम्बेड करता है।

3

गो में एक साधारण नियम। आप प्रकार के तरीकों चाहते हैं,

type A struct { B } 

करते हैं और यदि आप नहीं चाहते प्रकार के तरीकों, कर

type A B 

क्यों हम दूसरा रूप क्या ज़रूरत है? उदाहरण के लिए इंटरफेस,। कभी-कभी हम here जैसे इंटरफ़ेस को संतुष्ट करने के लिए कोई मान नहीं चाहते हैं। अन्य बार आपको केवल प्रकारों की आवश्यकता होती है, न कि इसकी विधियां।

गो आपको वही प्रकार प्राप्त करने की संभावना देता है, लेकिन एक खाली विधि सेट के साथ।