0

I have a quite complex struct that contains many interfaces with each different implementations. For en/decoding that struct in gob I seem to have to register every implementation that could be possibly used for every interface. So I end up with a method along these lines:

func registerImplementations() {
    gob.Register(&Type1{})
    gob.Register(&Type2{})
    gob.Register(&Type3{})
    gob.Register(&Type4{})
    ....

}

which I need to call before en/decoding. Is there an easier way to do this? Or should I look into possibilities for generating this method, since it's quite tedious to keep track of all possible implementations?

panmari
  • 3,627
  • 3
  • 28
  • 48

1 Answers1

0

The documentation says:

We must register the concrete type for the encoder and decoder (which would
normally be on a separate machine from the encoder). On each end, this tells the
engine which concrete type is being sent that implements the interface.

So, at some point, you're going to want to call gob.Register, but you do want your code to be maintainable. This leaves (broadly) two options:

  • Creating a function like you're doing now, calling each struct after one another.
    • Advantage: all your Register-calls in a list, so you'll easily spot if you miss one, and you surely won't register one twice.
    • Disadvantage: you'll have to update it when using another implementation. You'll also have to call this function some time before encoding/decoding.
  • Creating something like this:

    func Register(i interface{}) error {
        gob.Register(i)
        return nil
    }
    

    And then when writing a new implementation in your (let's say) dummy package, you can put this line below / above the interface declaration.

    var regResult = reg.Register(myNewInterface{})
    

This will be called on startup (because it's global).

  • Advantage: not having to update the registerImplementations method.
  • Disadvantage: you'll have your registers all across your code (which can consist of a lot of files) - so you might miss one.

As to which is better: I'll leave that up to you.

Etienne Bruines
  • 2,848
  • 3
  • 17
  • 25
  • Or, instead of inventing a `nil` error return (`gob.Register` has no return value) so you can cause initialization via a global variable assignment, it would likely be cleaner/simpler to just use [`init` function(s)](https://golang.org/ref/spec#Package_initialization) in the package/file that defines the type. – Dave C Apr 14 '15 at 17:55