将映射转换为结构

新手上路,请多包涵

我正在尝试在 Go 中创建一个通用方法,它将使用来自 — 的数据填充 struct map[string]interface{} 。例如,方法签名和用法可能如下所示:

 func FillStruct(data map[string]interface{}, result interface{}) {
    ...
}

type MyStruct struct {
    Name string
    Age  int64
}

myData := make(map[string]interface{})
myData["Name"] = "Tony"
myData["Age"]  = 23

result := &MyStruct{}
FillStruct(myData, result)

// result now has Name set to "Tony" and Age set to 23

我知道这可以使用 JSON 作为中介来完成;还有另一种更有效的方法吗?

原文由 tgrosinger 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 592
2 个回答

最简单的方法是使用 https://github.com/mitchellh/mapstructure

 import "github.com/mitchellh/mapstructure"

mapstructure.Decode(myData, &result)

如果你想自己做,你可以这样做:

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)
}

原文由 dave 发布,翻译遵循 CC BY-SA 4.0 许可协议

Hashicorp 的 https://github.com/mitchellh/mapstructure 库开箱即用:

 import "github.com/mitchellh/mapstructure"

mapstructure.Decode(myData, &result)

第二个 result 参数必须是结构的地址。

原文由 yunspace 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题