在 Golang 中将结构转换为映射的函数

新手上路,请多包涵

我想将结构转换为 Golang 中的映射。如果我可以在创建的地图中使用 JSON 标签作为键(否则默认为字段名称),那也很好。

编辑 2020 年 12 月 14 日

由于 structs repo 已存档,您可以改用 mapstructure

编辑 TL;DR 版本,2015 年 6 月 15 日

如果您想要将结构转换为映射的快速解决方案,请参阅已 接受的答案,对其进行投票并使用该包。

编码愉快! :)


原帖

到目前为止我有这个功能,我正在使用反射包但我不太了解如何使用该包,请耐心等待。

 func ConvertToMap(model interface{}) bson.M {
    ret := bson.M{}

    modelReflect := reflect.ValueOf(model)

    if modelReflect.Kind() == reflect.Ptr {
        modelReflect = modelReflect.Elem()
    }

    modelRefType := modelReflect.Type()
    fieldsCount := modelReflect.NumField()

    var fieldData interface{}

    for i := 0; i < fieldsCount; i++ {
        field := modelReflect.Field(i)

        switch field.Kind() {
        case reflect.Struct:
            fallthrough
        case reflect.Ptr:
            fieldData = ConvertToMap(field.Interface())
        default:
            fieldData = field.Interface()
        }

        ret[modelRefType.Field(i).Name] = fieldData
    }

    return ret
}

我还查看了 JSON 包源代码,因为它应该包含我需要的实现(或部分实现)但不太了解。

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

阅读 355
2 个回答

我也需要这样的东西。我正在使用一个将结构转换为地图的内部包。我决定将它与其他基于 struct 的高级函数一起开源。看一看:

https://github.com/fatih/structs

它支持:

  • 将结构转换为地图
  • 将结构的字段提取到 []string
  • 将结构的值提取到 []values
  • 检查结构是否已初始化
  • 检查传递的接口是结构还是指向结构的指针

您可以在此处查看一些示例:http: //godoc.org/github.com/fatih/structs#pkg-examples 例如,将结构转换为地图很简单:

 type Server struct {
    Name    string
    ID      int32
    Enabled bool
}

s := &Server{
    Name:    "gopher",
    ID:      123456,
    Enabled: true,
}

// => {"Name":"gopher", "ID":123456, "Enabled":true}
m := structs.Map(s)

structs 包支持匿名(嵌入式)字段和嵌套结构。该包提供了通过字段标签过滤某些字段的功能。

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

structmap[string]interface{}

 package main

import (
    "fmt"
    "encoding/json"
)

type MyData struct {
    One   int
    Two   string
    Three int
}

func main() {
    in := &MyData{One: 1, Two: "second"}

    var inInterface map[string]interface{}
    inrec, _ := json.Marshal(in)
    json.Unmarshal(inrec, &inInterface)

    // iterate through inrecs
    for field, val := range inInterface {
            fmt.Println("KV Pair: ", field, val)
    }
}

在这里去游乐场

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

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