गो

2012-11-04 13 views
5

में एक प्रकार की घोषणा के साथ रैपिंग स्ट्रक्चर को बदलें, मैं अपने मानक तरीकों को परिभाषित करने में सक्षम होने के लिए गो मानक लाइब्रेरी से regexp का विस्तार करना चाहता हूं। मैं निम्नलिखित struct का उपयोग करें:गो

type RichRegexp struct { 
    *regexp.Regexp 
} 

आप देख सकते हैं, इस struct लेकिन लिपटे regexp.Regexp कुछ भी नहीं होता है। तो मुझे आश्चर्य है कि क्या मैं इस तरह एक सरल प्रकार घोषणा के साथ इस जगह ले सकता है:

type RichRegexp regexp.Regexp 

लेकिन यह कैसे मैं निम्नलिखित समारोह तो लिखना चाहिए?

func Compile(expression string) (*RichRegexp, error) { 
    regex, err := regexp.Compile(expression) 
    if err != nil { 
     return nil, err 
    } 
    return &RichRegexp{regex}, nil // How to do this? 
} 

मैं अपने RichRegexp को regexp.Regexp परिवर्तित करने की कोशिश की लेकिन यह संकलन नहीं किया। एक कस्टम प्रकार को वापस करने के लिए सामान्य पैटर्न क्या है जो अंतर्निहित प्रकार को लपेटता है?

उत्तर

3
package main 

import (
     "regexp" 
) 

type RichRegexp regexp.Regexp 

func Compile(expression string) (*RichRegexp, error) { 
     regex, err := regexp.Compile(expression) 
     if err != nil { 
       return nil, err 
     } 

     return (*RichRegexp)(regex), nil 
} 

func main() { 
    Compile("foo") 
} 

इसके अलावा यहाँ: http://play.golang.org/p/cgpi8z2CfF

5

आप एक रूपांतरण का उपयोग कर सकते हैं, लेकिन इस मामले में यह आवश्यक है, कि अपने प्रकार परिभाषा एक सूचक नहीं है:

type MyRegexp *regexp.Regexp // Doesn't work 

यह the spec के द्वारा समर्थित है :

रिसीवर प्रकार फॉर्म टी या * टी का होना चाहिए जहां टी एक प्रकार का नाम है। टी द्वारा निर्दिष्ट प्रकार को रिसीवर बेस प्रकार कहा जाता है; यह एक सूचक या इंटरफ़ेस प्रकार नहीं होना चाहिए और इसे विधि के रूप में उसी पैकेज में घोषित किया जाना चाहिए। विधि को आधार प्रकार से बाध्य कहा जाता है और विधि का नाम केवल उस प्रकार के चयनकर्ताओं के भीतर दिखाई देता है।

लेकिन, आप यह कर सकते हैं:

type MyRegexp regexp.Regexp 

आप मूल्यों संभाल रहे हैं के रूप में अब, आप निम्न कर सकते हैं:

x := regexp.MustCompile(".*") 
y := MyRegexp(*x) 

और आप अपने खुद के regexp प्रकार है।

खेल में पूर्ण कोड: http://play.golang.org/p/OWNdA2FinN

एक सामान्य पद्धति के रूप में, मैं कहूंगा कि होगा:

  • यदि यह परिवर्तन की संभावना नहीं है और आप एक प्रकार का उपयोग करें, मनमाने ढंग से मान संग्रहीत की जरूरत नहीं है रूपांतरण।
  • यदि आपको अपने एम्बेडेड प्रकार के साथ मूल्यों को स्टोर करने की आवश्यकता है, तो struct का उपयोग करें।
  • यदि आपका कोड बदलने की संभावना है और बड़ी किस्मों की सहायता करने की आवश्यकता है, एक इंटरफ़ेस परिभाषित करें और एम्बेडिंग/प्रकार रूपांतरण का उपयोग न करें।
+0

'MyRegexp (* x)' मेरे मामले में काम नहीं करता है, क्योंकि मुझे एक सूचक वापस करना है। अगर मैं 'y: = और MyRegexp (* x) 'कोशिश करता हूं' मुझे त्रुटि मिलती है 'MyRegexp (* x)' http://play.golang.org/p/HbVoAVM1RY का पता नहीं ले सकता है। – deamon

+1

यदि आप एक पॉइंटर चाहते हैं, तो इसे 'MyRegexp' के सूचक के रूप में परिवर्तित करें:' (* MyRegexp) (x) '। ध्यान दें कि 'x' के dereferenciation के लिए अब कोई आवश्यकता नहीं है, क्योंकि अब हम पॉइंटर्स से निपट रहे हैं। अतिरिक्त सूचनाओं के लिए [spec] (http://golang.org/ref/spec#Conversions) देखें :) – nemo

+0

आपकी स्पष्टीकरण के लिए धन्यवाद। '(* MyRegexp) (x)' क्या 'jnml' भी सुझाया गया है। – deamon