2012-09-12 17 views
10

मुझे आरपीसी शैली इंटरफेस को परिभाषित करने के लिए गो में इंटरफेस का उपयोग करने का विचार है।क्या मैं गो में प्रतिबिंब का उपयोग करके एक नया फ़ंक्शन बना सकता हूं?

type MyService interface{ 
    Login(username, password string) (sessionId int, err error) 
    HelloWorld(sessionId int) (hi string, err error) 
} 

मुझे क्या करना चाहते हैं कि इंटरफ़ेस को लागू करने के लिए उपयोग प्रतिबिंब है, अनुवाद विधि, RPC कॉल में कॉल इनपुट पैरामीटर मार्शलिंग, और Unmarshaling: तो किसी दिए गए सेवा के लिए, मैं इस तरह एक अंतरफलक बना सकता है विधि के आउटपुट में वापस परिणाम। मुझे पता है कि अगर मैं इनपुट पैरामीटर का एक [] इंटरफेस {} प्राप्त कर सकता हूं तो मैं सेवा कॉल करने के लिए प्रतिबिंब का उपयोग कर सकता हूं। हालांकि मुझे प्रतिबिंब का उपयोग करने के लिए कोई तरीका नहीं दिखता है जो गतिशील रूप से एक मूल्य बनाता है जो मेरे प्रतिबिंब-उपयोग कार्यों को कॉल करके इंटरफेस को कार्यान्वित करेगा। क्या किसी को भी ऐसा करने का तरीका पता है, यहां तक ​​कि असुरक्षित का उपयोग भी?

+0

नीचे दिए गए दोनों उत्तर सटीक और सत्य हैं। चूंकि इस पर एक बक्षीस है, इसलिए आपको उनमें से एक को अपने उत्तर के रूप में चिह्नित करना चाहिए। आप किसी और को कुछ और नहीं कहेंगे। –

उत्तर

8

आप उस प्रकार की ऑब्जेक्ट को तुरंत चालू करने के लिए प्रतिबिंब के माध्यम से संलग्न तरीकों के साथ एक प्रकार नहीं बना सकते हैं।

आप इसे unsafe पैकेज के माध्यम से संभवतः हैकरी के साथ प्राप्त कर सकते हैं। लेकिन फिर भी, यह एक बड़ा दर्द होगा।

यदि आप जिस समस्या को हल करने की कोशिश कर रहे हैं उस पर अधिक विस्तार से बताया गया है, तो समुदाय इसे हल करने के वैकल्पिक तरीकों के साथ आ सकता है।

संपादित करें (23. जुलाई 2015): गो 1.5 के साथ शुरू होने पर reflect.FuncOf और reflect.MakeFunc है, जो वास्तव में आप चाहते हैं।

+0

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

+1

काफी नहीं। प्रतिबिंबित करें। GoakeFunc पहले से ही 1.1 के बाद से अस्तित्व में है। प्रतिबिंबित करें। FuncOf 1.5 में जोड़ा गया था, लेकिन विधियों के निर्माण को सक्षम नहीं करता है, जो मनमाने ढंग से इंटरफेस को लागू करने के लिए आवश्यक हैं। हमें जो चाहिए वह नए "नामित" प्रकार बनाने और रनटाइम पर उन प्रकारों पर विधियों को परिभाषित करने की क्षमता होगी। – Matt

0

मुझे लगता है कि अगर आप reflect.Type इंटरफ़ेस को पूरी तरह कार्यान्वित कर सकते हैं, तो आप यह प्राप्त करना संभव हो सकता है, जिसे आप (अप्रत्याशित तरीके) नहीं कर सकते हैं। तो हो सकता है कि unsafe_New का उपयोग कर अपने कस्टम प्रकार को तुरंत चालू करना संभव हो।

सब कुछ ऐसा करने का अच्छा विचार नहीं है।

आप जो चाहते हैं उसके लिए अगली सबसे अच्छी बात शायद gob जैसी कुछ चीज़ों का उपयोग करना है। आप गोब का इंटरमीडिएट भाषा के रूप में उपयोग कर सकते हैं, प्रतिबिंब का उपयोग करके अपने इंटरफ़ेस से विधियों को पढ़ सकते हैं, उन्हें गोब के रूप में लिख सकते हैं और वास्तविक गो ऑब्जेक्ट्स में बनाए गए गोब कोड को डीकोड कर सकते हैं। लेकिन मुझे यकीन नहीं है कि यह इसके लायक है या नहीं।

अधिकतर समय आप क्लाइंट साइड पर अपने इंटरफ़ेस को मैन्युअल रूप से कार्यान्वित करके और विधि कॉल को अग्रेषित करके सुरक्षित रखते हैं।

+0

'unsafe_New' क्या है? – thwd

+1

'unsafe_New'' रनटाइम 'पैकेज में परिभाषित फ़ंक्शन है और नई ऑब्जेक्ट्स बनाने के लिए' प्रतिबिंबित 'पैकेज द्वारा उपयोग किया जाता है। उदाहरण के लिए ''शून्य'] (http://golang.org/src/pkg/reflect/value.go#L1729) में 'प्रतिबिंबित' का कार्य किया जाता है। – nemo

5

ऐसा प्रतीत होता है कि प्रतिबिंबित पैकेज गो 1.1: reflect.MakeFunc में नए मनमाने ढंग से टाइप किए गए कार्यों को बनाने की क्षमता प्राप्त करेगा।

(जवाब में जोड़ा निम्नलिखित @nemo करने के लिए)

एक अंतरफलक के बजाय

, एक एक struct प्रकार बना सकते हैं: भाषा के स्थिर प्रकृति के कारण

type MyService struct{ 
    Login func(username, password string) (sessionId int, err error) 
    HelloWorld func(sessionId int) (hi string, err error) 
} 

autorpc.ImplementService(&MyService, MyServiceURL) 
session, err := MyService.Login(username, password) 
stringout, err := MyService.HelloWorld(session) 
+1

हालांकि यह आपको एक प्रकार का संघ नहीं देगा। तो इंटरफेस का कोई मनमाने ढंग से कार्यान्वयन नहीं। – nemo

+0

@nemo आप बिल्कुल सही हैं लेकिन ऊपर मेरा अपडेट देखें। – Matt

+0

आह हाँ, यह अब संभव है। बुरा नहीं। – nemo

0

, वहाँ कोई रास्ता नहीं है समय पर इस बिंदु पर गतिशील रूप से एक इंटरफ़ेस को कार्यान्वित करने के लिए।

मैं समझता हूँ कि आप क्या हासिल करना चाहते हैं और वहाँ अन्य परिदृश्यों कि यह भी एक और अधिक उन्नत प्रतिबिंब क्षमता का लाभ होगा (इकाई परीक्षण के लिए उदाहरण के लिए एक अच्छा मजाक ढांचा)


कहा कर रहे हैं, वहाँ एक रास्ता है कि आप इस समस्या को हल कर सकते हैं। आप अपना खुद का टूल लिख सकते हैं जो एक गो स्रोत कोड फ़ाइल उत्पन्न करता है जिसमें एक इंटरफेस के दिए गए आरपीसी कार्यान्वयन होते हैं।

आपको स्रोत इंटरफ़ेस को पार्स और संसाधित करने के लिए AST लाइब्रेरी, साथ ही अन्य लोगों का उपयोग करना होगा।

उस पथ को नीचे जाने के बाद (gostub उपकरण; संदर्भ के रूप में उपयोग कर सकते हैं), मैं कह सकता हूं कि यह बिल्कुल मजेदार और आसान नहीं है। फिर भी, अंतिम परिणाम सहनशील है क्योंकि गो go:generate कार्यक्षमता प्रदान करता है, जो इंटरफ़ेस बदल जाने के बाद कम से कम टूल को पुन: चलाता है, एक टैड आसान होता है।

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

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