To avoid some extended discussion in comments I'm just going to make an answer explaining the two approaches I would choose from. Generally speaking, I would avoid the reflective method. There are cases where it is called for but most of the time the more verbose, literal, simple code will be better, even if it's a few more lines and there is some overlap between what the methods do.
So, starting with the simple example. Suppose you got 3 types, GroceryStore
, ComputerStore
, and CornerStore
. In whatever package each type is defined in, it is fairly common to define some constructor like methods (they're not technically constructors, just package scoped methods that instantiate a type and return it but same purpose). So an example would be;
func NewComputerStore(store Store) *ComputerStore {
return &ComputerStore{
Name: store["Name"],
Location: store["Location"],
//ect
}
}
Of course the example above is completely unsafe. In reality you need to use the v, ok := myMape["key"]
syntax and then assign if ok
and do whatever if not (probably some combination of assign default value, log error, and throw error).
Now if you want a generalized method... It typically look something more like this (note this is untested and is more pseudo code than a working example);
func (s *Store) ConvertToObject(obj interface{}) error {
val := reflect.ValueOf(obj)
for i := 0; i < val.NumField(); i++ {
switch v := val.Field(i).(type) {
case int64:
val.Field(i).SetInt(strconv.Atoi(s[val.Field(i).Name]))
}
}
}
So the basic idea of the code above is this. You're starting with a store map. The caller knows what type that map is supposed to be. They call this method passing a new instance of that type. In the method we don't really care what the type is, we care what the type of it's fields are. So I iterate all the fields on the object passed in. Each field is put through the type switch (since I'll need a string to X conversion for every type that is present in the structs this method should work with, or at least a decent base case), in the case for each type you can do assignment using the field name to look up it's value in the Store
map and converting from string to X.
Hope that makes sense. I can follow up if it doesn't really clarify the approach. Remember the code above is not intended to run. Also, I've ignored all error handling which you will need lots of to make a generalized function work (what to do if conversion fails? What if type isn't recognized? What about all the other possible errors that won't be common place?).