Converting map to struct

前端 未结 6 1359
灰色年华
灰色年华 2020-12-04 05:46

I am trying to create a generic method in Go that will fill a struct using data from a map[string]interface{}. For example, the method signature an

6条回答
  •  遥遥无期
    2020-12-04 06:36

    The simplest way would be to use https://github.com/mitchellh/mapstructure

    import "github.com/mitchellh/mapstructure"
    
    mapstructure.Decode(myData, &result)
    

    If you want to do it yourself, you could do something like this:

    http://play.golang.org/p/tN8mxT_V9h

    func SetField(obj interface{}, name string, value interface{}) error {
        structValue := reflect.ValueOf(obj).Elem()
        structFieldValue := structValue.FieldByName(name)
    
        if !structFieldValue.IsValid() {
            return fmt.Errorf("No such field: %s in obj", name)
        }
    
        if !structFieldValue.CanSet() {
            return fmt.Errorf("Cannot set %s field value", name)
        }
    
        structFieldType := structFieldValue.Type()
        val := reflect.ValueOf(value)
        if structFieldType != val.Type() {
            return errors.New("Provided value type didn't match obj field type")
        }
    
        structFieldValue.Set(val)
        return nil
    }
    
    type MyStruct struct {
        Name string
        Age  int64
    }
    
    func (s *MyStruct) FillStruct(m map[string]interface{}) error {
        for k, v := range m {
            err := SetField(s, k, v)
            if err != nil {
                return err
            }
        }
        return nil
    }
    
    func main() {
        myData := make(map[string]interface{})
        myData["Name"] = "Tony"
        myData["Age"] = int64(23)
    
        result := &MyStruct{}
        err := result.FillStruct(myData)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(result)
    }
    

提交回复
热议问题