Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace wrapping struct with a type declaration in Go

I want to extend the regexp from the Go standard library to be able to define my own methods. I use the following struct:

type RichRegexp struct {
    *regexp.Regexp
}

As you can see, this struct contains nothing but the wrapped regexp.Regexp. So I wonder whether I could replace this with a simple type declaration like this:

type RichRegexp regexp.Regexp

But how should I write the following func then?

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?
}

I tried to convert regexp.Regexp to my RichRegexp but it didn't compile. What is the general pattern to return a custom type which wraps a underlying type?

like image 255
deamon Avatar asked Nov 04 '12 13:11

deamon


1 Answers

You can use a conversion, but in this case it is necessary, that your type definition is not a pointer:

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

This is backed by the spec:

The receiver type must be of the form T or *T where T is a type name. The type denoted by T is called the receiver base type; it must not be a pointer or interface type and it must be declared in the same package as the method. The method is said to be bound to the base type and the method name is visible only within selectors for that type.

However, you can do this:

type MyRegexp regexp.Regexp

As you're handling values now, you can do the following:

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

And you have your own regexp type.

Full code at play: http://play.golang.org/p/OWNdA2FinN

As a general pattern, I would would say:

  • If it's unlikely to change and you don't need to store arbitrary values, use a type conversion.
  • If you need to store values along with your embedded type, use a struct.
  • If your code is likely to change and needs to support large varieties of things, define an interface and don't use embedding / type conversion.
like image 139
nemo Avatar answered Oct 26 '22 06:10

nemo