2015-12-04 8 views
6

क्या एम्बेडेड structs का उपयोग किये बिना किसी प्रकार के तरीकों का उत्तराधिकारी संभव है?गोलांग एम्बेडेड संरचना

कोड के पहले स्निपेट कोड कि Node में Property struct एम्बेड करता है काम कर रहा है और मैं node.GetStringProperties पर एक विधि है कि फोन करने में सक्षम हूँ। मुझे इस बारे में पसंद नहीं है जब मैं Node शुरू करता हूं, मेरे पास Properties संरचना को आरंभ करने के लिए (?) है। क्या इसके चारों ओर एक रास्ता है?

package main 

import "fmt" 

type Properties map[string]interface{} 

func (p Properties) GetString(key string) string { 
    return p[key].(string) 
} 

type Nodes map[string]*Node 

type Node struct { 
    *Properties 
} 

func main() { 
    allNodes := Nodes{"1": &Node{&Properties{"test": "foo"}}} // :'(
    singleNode := allNodes["1"] 
    fmt.Println(singleNode.GetString("test")) 
} 

आखिरकार, मैं निम्नलिखित की तरह कुछ करना चाहता हूं। जहां Node टाइप Properties है और प्रारंभ में Property संरचना को प्रारंभ करने की आवश्यकता नहीं है। निम्नलिखित कोड काम नहीं करता है लेकिन यह स्पष्ट हो सकता है कि मेरा लक्ष्य क्या है।

package main 

import "fmt" 

type Properties map[string]interface{} 

func (p Properties) GetString(key string) string { 
    return p[key].(string) 
} 

type Nodes map[string]*Node 

type Node Properties 

func main() { 
    allNodes := Nodes{"1": &Node{"test": "foo"}} // :) 
    singleNode := allNodes["1"] 
    fmt.Println(singleNode.GetString("test")) // :D 
} 
मैं और अधिक structs कि Properties के तरीकों जिसके कारण मैं पूछ रहा हूँ का उपयोग करेगा जोड़ने होंगे

। अगर मेरे पास केवल Node था, तो मेरे पास Node के लिए विधियां होंगी और किया जाएगा। लेकिन क्योंकि मैं एक से अधिक Node होगा मैं यह सब structs एम्बेड कि Properties

मैं सटीक समस्या के लिए और अधिक लगता है बिना, मैं Node से Properties तरीकों का उपयोग करना चाहते हैं एक ही तरीके से जोड़ने के लिए एक तरह से बेमानी लगता है Properties आरंभ करें।

+1

मुझे लगता है जैसे आप शायद उन कार्यों को लिख सकते हैं जो 'Properties' ऑब्जेक्ट का उदाहरण स्वीकार करते हैं और इसे संलग्न करने के बजाय इसे संचालित करते हैं। इस प्रकार गो में एम्बेडिंग कैसे काम करती है ... इसलिए मुझे यकीन नहीं है कि इसके चारों ओर एक रास्ता है। संरचना, विरासत नहीं। –

+0

एम्बेडिंग को किसी कारण के लिए एम्बेडिंग कहा जाता है;) सभी गुण फ़ील्ड नोड में एम्बेडेड हो जाते हैं। – kostya

उत्तर

3

तो आप यहां जाने की मूर्खता में भाग रहे हैं। एम्बेडिंग एकमात्र तरीका है जिसमें एक संरचना के तरीकों को किसी अन्य संरचना पर मौजूद होने के लिए "प्रचारित" किया जा सकता है। हालांकि यह सहज महसूस करता है कि type Node PropertiesNode पर Properties विधियों का खुलासा करना चाहिए, उस वाक्यविन्यास का प्रभाव Node के लिए Properties के मेमोरी लेआउट को लेने के लिए है, लेकिन इसकी कोई भी विधि नहीं है।

यह स्पष्ट नहीं करता कि यह डिज़ाइन पसंद क्यों किया गया था लेकिन Go Spec कम से कम विशिष्ट होने पर विशिष्ट है। यदि आप इसे ठीक से पढ़ते हैं, जैसा कि कोई प्रतीत होता है, तो यह बहुत सटीक नहीं है:

इंटरफ़ेस प्रकार का विधि सेट इसका इंटरफ़ेस है। किसी भी अन्य प्रकार टी सभी तरीकों के होते हैं की विधि सेट रिसीवर प्रकार टी के साथ घोषित

GetString प्रकार Properties के एक रिसीवर नहीं Node, गंभीरता से, कल्पना की व्याख्या की तरह आप कोई कल्पना के साथ एक एकाउंटेंट रहे है। इसके साथ कहा गया:

आगे के नियम अज्ञात क्षेत्रों वाले structs पर लागू होते हैं, जैसा कि संरचना प्रकारों पर अनुभाग में वर्णित है।

...

एक क्षेत्र या विधि में एक struct एक्स एक गुमनाम मैदान के च पदोन्नत कहा जाता है x.f एक कानूनी चयनकर्ता कि अर्थ है कि क्षेत्र या विधि च है।

प्रचारित फ़ील्ड एक संरचना के सामान्य क्षेत्रों की तरह कार्य करते हैं सिवाय इसके कि वे संरचना के समग्र अक्षर में फ़ील्ड नामों के रूप में उपयोग नहीं किए जा सकते हैं।

  • एस एक गुमनाम क्षेत्र टी शामिल है, तो एस की विधि सेट और:

    एक struct प्रकार S और एक प्रकार टी नामित देखते हुए पदोन्नत तरीकों इस प्रकार struct की विधि सेट में शामिल किए गए हैं * एस में रिसीवर टी के साथ प्रचारित विधियां शामिल हैं। * एस के विधि सेट भी में रिसीवर * टी के साथ प्रचारित विधियां शामिल हैं।

  • यदि एस में अज्ञात फ़ील्ड * टी है, तो एस और * एस के विधि सेट में रिसीवर टी या * टी के साथ प्रचारित विधियां शामिल हैं।

कि लाइन समग्र शाब्दिक के बारे में इस बात यह है कि आप आपके द्वारा बनाए गए हर Node अंदर Properties घोषित करने के लिए मजबूर करता है।

पेज। हाय जेफ!

+0

हाय डेविड! मुझे यह जानने में दिलचस्पी होगी कि वह डिज़ाइन पसंद क्यों किया गया था। यह शायद लाइनों के बीच कहीं गहरी कल्पना में है। उम्मीद है आपके साथ सब कुशल मंगल है। – Jeff

+0

@ जेफ: यहां डिज़ाइन विकल्प यह है कि गो के पास विरासत नहीं है, और इसमें विधि अधिभार नहीं है। एम्बेडिंग स्वचालित प्रतिनिधिमंडल के लिए एक सुविधाजनक तरीका है, जिसमें चयनकर्ता फ़ील्ड और विधियों को बढ़ावा दे सकते हैं (आप उन्हें हमेशा भी कॉल कर सकते हैं) के बारे में विशिष्ट नियमों के साथ, कुछ भी "विरासत" नहीं है। – JimB

1

आपके अंतिम प्रश्न का संक्षिप्त उत्तर केवल नहीं है।

वहाँ प्रकार घोषणा और में एम्बेड, आप मैन्युअल रूप से काम कर रहे अपने पिछले उदाहरण बना सकते हैं Node और Properties के बीच एक प्रकार रूपांतरण बनाने के बीच एक बड़ा अंतर है:

package main 

import "fmt" 

type Properties map[string]interface{} 

func (p Properties) GetString(key string) string { 
    return p[key].(string) 
} 

type Nodes map[string]*Node 

type Node Properties 

func main() { 
    allNodes := Nodes{"1": &Node{"test": "foo"}} // :) 
    singleNode := allNodes["1"] 
    fmt.Println(Properties(*singleNode).GetString("test")) // :D 
} 

लेकिन यह स्पष्ट रूप से है कि है कि तुम क्या नहीं चाहते हैं, आप टाइपिंग एलियासिंग के सिंटैक्स के साथ एक स्ट्रक्चर एम्बेड करना चाहते हैं, जो में संभव नहीं है, मुझे लगता है कि आपको अपने पहले दृष्टिकोण से अटक जाना चाहिए और इस तथ्य को अनदेखा करना चाहिए कि कोड अनावश्यक और बदसूरत है।

संबंधित मुद्दे