2015-03-18 5 views
14

में जेनेरिक के बिना जेनरिक फ़ंक्शन लिखना मुझे पता है कि गो भविष्य में जेनेरिक नहीं होगा और अन्य संरचनाओं द्वारा उन्हें बदलने के लिए कुछ सिफारिशें हैं। लेकिन नीचे मेरे उदाहरण के साथ मैं अटक गया।गो लैंग

func P(any interface{}, err error) (interface{}) { 
    if err != nil { 
     panic("error: "+ err.Error()) 
    } 
    return any 
} 

आप अंदाज़ा लगा सकते हैं, मैं सिर्फ किसी भी त्रुटि पर विफल कोशिश कर रहा हूँ और बस जाता है कि लौटने दो परिणाम किसी भी समारोह के आसपास P() रखना चाहते हैं और दूसरा कोई त्रुटि है। यह ठीक काम कर रहा है, लेकिन any इसकी प्रकार की जानकारी खो रहा है और परिणाम में केवल एक खाली इंटरफ़ेस है।

जैसा कि मैं lib कार्यों को भी कॉल कर रहा हूं, मुझे इंटरफेस या प्रतिबिंब के साथ इसका समाधान करने का कोई तरीका नहीं दिख रहा है।

कोई भी विचार? क्या मैं पूरी तरह से गलत ट्रैक या लक्ष्य के करीब हूं?

+5

ऐसा मत करो। बस 'अगर गलती है! = Nil' थोड़ा सा लिखो और यह कम परेशान हो जाता है।यदि आप कुछ लिखते हैं जहां पूरी तरह दोहराया जाता है 'त्रुटि! = नील आपके कोड का बहुत अधिक गठन करता है, तो आप [सहायताकर्ता लिख ​​सकते हैं जो कहीं भी त्रुटि असाइन करते हैं] (http://blog.golang.org/errors-are-values), या यदि कुछ या सभी त्रुटियां निश्चित रूप से पूरे ऑपरेशन को डुबोती हैं, तो 'पैनिक-ऑन-अप्राप्य-त्रुटि रैपर' जैसे 'mustWrite' लिखें और फिर अपने पैकेज से बाहर निकलने से पहले पैनिक से' पुनर्प्राप्त करें 'लिखें। – twotwotwo

+2

मैं आपको कोड कोड में "भाषा एक्स के काम करने के तरीके" फिट करने की कोशिश करना बंद कर दूंगा। जाओ में हर जगह स्पष्ट त्रुटि है और कोई वास्तविक अपवाद नहीं है (आतंक/पुनर्प्राप्ति सी ++/जावा अपवादों के समान नहीं है)। विशेष रूप से, ** कभी भी ** एक गो पैकेज नहीं लिखें जो 'os.Open'' पर वापस आ रहा है जैसे 'os.PathError'। –

+0

भले ही आपको कभी भी ऐसी जगह मिल जाए जहां आप त्रुटियों पर घबराहट करना चाहते हैं, बस 'दहशत (गलती) '। अगर पुनर्प्राप्त किया गया तो आउटपुट लगभग समान होगा लेकिन 'पुनर्प्राप्ति' को स्ट्रिंग प्रस्तुति के बजाय मूल त्रुटि मिल जाएगी। –

उत्तर

11

एक समाधान go generate अपने P() समारोह, प्रत्येक ठोस प्रकार आप के साथ काम करने की जरूरत के लिए एक करने के लिए किया जाएगा।

कि उन lib कार्यों आसान (प्रयोग करेंगे उत्पन्न कार्यान्वयन बुला, ठोस पी के बाद से) होगा इंटरफेस के बजाय सही प्रकार {}।

4

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

आपको प्रत्येक प्रकार के लिए ऐसा फ़ंक्शन बनाना है जिसे आप समर्थन देना चाहते हैं। ध्यान दें कि मानक पुस्तकालय पहले से ही इन नाम MustXXX(), जो आप बॉक्स से बाहर का उपयोग कर सकते, उदाहरण के लिए के तहत जा रहा से कुछ में शामिल हैं:

template.Must(t *Template, err error) *Template

या "समान" कार्य करता है जो error को दबाने लेकिन अगर एक अभी भी होती है, तो घबरा, उदाहरण के लिए:

regexp.MustCompile(str string) *Regexp (error को दबा लेकिन घबरा अगर str एक वैध regexp नहीं है)

3

यदि आप बुरा विचार पर योजना सिर्फ त्रुटियों पर डर () या उन्हें लॉगिंग, तो बस ऐसा करने के लिए एक फ़ंक्शन को परिभाषित करें और इसका उपयोग करें। जैसे

func checkErr(err error) { 
    if err != nil { 
     log.Println(err) 
    } 
} 

// ... 

func foo() { 
    a, err := doA() 
    checkErr(err) 
    b, err := doB() 
    checkErr(err) 
    // etc. 
} 

उपयोगकर्ता twotwotwo पहले से ही Errors are values लेख कि कैसे त्रुटि हैंडलिंग कम दोहराव कराने संबंधी उदाहरण दिखाता है से जुड़ा हुआ है। लेकिन मैं सिर्फ पूरे if err != nil चीज़ लिखने की अनुशंसा करता हूं, क्योंकि मेरे अनुभव में प्रत्येक तीसरी त्रुटि, यदि नहीं, तो कुछ अतिरिक्त हैंडलिंग की आवश्यकता होती है।

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