1

I am trying to create a generic function that can accept a key string and a reference to an object.

The function reads a key's content, which is a serialized byte array out of an original object of the same type and it should assign that (deserializing) to an empty structure of that same type. The function wants to be generic, so it can serialize a type A as well as B or []C

Here is what I tried to do:

func GetObject(key string, thing interface{}) error {
    var buf bytes.Buffer        
    dec := gob.NewDecoder(&buf)
    err := dec.Decode(thing)
    if err != nil {
        log.Errorf(cs.ctx, "cloud store - GetObject - decode error:", err)
        return err
    }
    return nil
}

This is how I try to invoke the above function:

newThing := MyStruct{}
err := GetObject("a123", &newThing)

The last lines about cause a runtime error:

decode error:%!(EXTRA *errors.errorString=EOF)

the question:

  • is the interface approach correct for this purpose (allow the function be used generically) ?
  • The serialization error ( using Gob ) seems to be problematic. Any suggestions on how to rectify that ?
4
  • 1
    Your code appears to be backwards. If you were decoding wouldn't you pass in a byte slice? Commented Apr 5, 2016 at 14:51
  • 1
    Don't do that, you'll hurt yourself. Forget anything "generic". If you want to load several objects from some backend: Have them all implement a specific interface which has all methods needed for the []byte to object deserialization. Commented Apr 5, 2016 at 14:58
  • @ZanLynx you are right. I missed the decoder read from the store in the example... I will update the code shortly. Commented Apr 5, 2016 at 15:01
  • I was able to resolve. Since this was the first attempt to use interfaces like this, I was skeptic on that layer, but instead I forgot to add the byte data instead. So what was missing is: content, _ := cs.Get(fileName); buffer := bytes.NewBuffer(content); dec := gob.NewDecoder(buffer) Commented Apr 5, 2016 at 15:10

1 Answer 1

1

The concept of interfaces is correct. The issue was related to a missing getter from the persistence store and how to create a buffer out of its []byte content:

func GetObject(key string, thing interface{}) error {
    content, _ := SomePersistanceStoreGet(fileName)
    buffer := bytes.NewBuffer(content)
    dec := gob.NewDecoder(buffer)
   err := dec.Decode(thing)
    if err != nil {
        log.Errorf("decode error: %v", err)
        return err
    }
    return nil
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.