Oguz Bilgic
Oguz Bilgic

Reputation: 3480

Map <-> struct type casting

Currently this is the method I use to convert map[string]interface{} to Message struct

byteBlob, err := json.Marshal(messageMap)
if err != nil {
    return nil, err
}

message := &Message{}
err = json.Unmarshal(byteBlob, message)
if err != nil {
    return nil, err
}

I found json package to hack my way through this, but what is the right way to do this conversion? obviously without using json package

Upvotes: 1

Views: 323

Answers (1)

James Henstridge
James Henstridge

Reputation: 43899

The encoding/json package makes use of the reflect package to marshal and unmarshal messages.

So you can do the same with reflect directly. If you don't need the support for nested structs and arrays, the following should do the trick:

message := Message{}

v := reflect.ValueOf(&message).Elem()
for key, value := range messageMap {
    field := v.FieldByName(key)
    if !field.IsValid() {
        // or handle as error if you don't expect unknown values
        continue
    }
    if !field.CanSet() {
        // or return an error on private fields
        continue
    }
    field.Set(reflect.ValueOf(value))
}

You can experiment further with this code in the playground.

Upvotes: 2

Related Questions