从参数动态填充结构

时间:2018-11-12 08:24:29

标签: json go dynamic unmarshalling

我有以下结构可以按预期工作 数据,我可以

type Service struct {
    Resources    []struct {
        Model struct {
            Name                string `json:"name"`
            Credentials         struct {
                path string `json:"path"`
                Vts struct {
                    user string `json:"user"`
                    id    string `json:"id"`
                    address      string `json:"address"`
                } `json:"vts"`
            } `json:"credentials"`
        } `json:"model"`
    } `json:"resources"`
}

service:= Service{}
err := json.Unmarshal([]byte(data), &service

数据如下,

service1

{
    "resources": [
        "model": {
          "name": "cred",
          "credentials": {
            "path": "path in fs",
            "vts": {
              "user": "stephane", 
              "id": "123",
              "address": "some address"
            }
          },
        }
      },

例如,现在有些服务在vts下提供其他数据,例如,我们现在有3个字段(用户/ ID /地址),但是某些服务(service1)可以提供其他数据,例如email,secondName等。但是这里最大的问题是 我需要从(服务2)教育,薪水等参数中获取信息

Service2

{
    "resources": [
        "model": {
          "name": "cred",
          "credentials": {
            "path": "path in fs",
            "vts": {
              "user": "stephane",
              "id": "123",
              "address": "some address",
              "email" : "some email",
              "secondName" : "secondName"
            }
          },
        }
      },

服务N

{
    "resources": [
        "model": {
          "name": "cred",
          "credentials": {
            "path": "path in fs",
            "vts": {
              "user": "stephane",
              "id": "123",
              "address": "some address",
              "salary" : "1000000"
            }
          },
        }
      },

当然,如果我事先知道 字段,则可以将它们全部放入结构中并使用omitempty ,但我不知道,我只是将其作为参数函数(新的属性名称),某些服务可以在此结构中提供10个以上的字段(我应该将它们的属性名称作为args[]的函数来获取),但是我不知道它们预先,这应该是动态的....在Golang中有没有很好的方法来处理它?

1 个答案:

答案 0 :(得分:4)

如果您不预先知道字段,则不要使用结构,而要使用也具有“动态”性的东西:地图。

type Service struct {
    Resources []struct {
        Model struct {
            Name        string `json:"name"`
            Credentials struct {
                Path string                 `json:"path"`
                Vts  map[string]interface{} `json:"vts"`
            } `json:"credentials"`
        } `json:"model"`
    } `json:"resources"`
}

map[sting]interface{}可以保存任何类型的值。如果您知道所有字段都将保留一个string值,则也可以使用一个map[string]string,以便更轻松地使用它。

带有输入JSON的示例:

{
    "resources": [
      {
        "model": {
          "name": "cred",
          "credentials": {
            "path": "path in fs",
            "vts": {
              "user": "stephane", 
              "id": "123",
              "address": "some address",
              "dyn1": "d1value",
              "dyn2": "d2value"
            }
          }
        }
      }
    ]
}

测试:

service := Service{}
err := json.Unmarshal([]byte(data), &service)
fmt.Printf("%q %v", service, err)

输出(在Go Playground上尝试):

{[{{"cred" {"path in fs" map["dyn2":"d2value" "user":"stephane" "id":"123" 
    "address":"some address" "dyn1":"d1value"]}}}]} <nil>

现在,如果您想从Vts映射中收集一组键的值,则可以通过以下方式进行操作:

args := []string{"dyn1", "dyn2"}
values := make([]interface{}, len(args))
for i, arg := range args {
    values[i] = service.Resources[0].Model.Credentials.Vts[arg]
}
fmt.Println(values)

上面的输出将是(在Go Playground上尝试):

[d1value d2value]
相关问题