dongqiyou0303 2018-11-12 08:24
浏览 109
已采纳

从参数动态填充结构

I've the following struct which works as expected Im getting data and I was able

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

The data is like following,

service1

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

Now some services providing additional data under vts for example now we have 3 fields (user/id/address) but some services (service1) can provides additional data like email, secondName ,etc . but the big problem here is that I need to get it from parameters since (service 2) education, salary etc

Service2

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

service N

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

Of course If I know in advance the fields I can put them all in the struct and use omitempty but I dont know, I just get it as parameter to the function (the new properties names) , some service can provide 10 more fields in this struct (which I should get the properties name of them as args[]to the functions) but I don't know them in advance, this should be dynamic somehow ....is there a nice way to handle it in Golang ?

  • 写回答

1条回答 默认 最新

  • drtohng5613 2018-11-12 08:45
    关注

    If you don't know the fields in advance, then don't use a struct but something that is also "dynamic": a map.

    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{} can hold values of any type. If you know all fields will hold a string value, you may also use a map[string]string so it will be easier to work with it.

    Example with input JSON:

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

    Testing it:

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

    Output (try it on the Go Playground):

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

    Now if you want to collect values from the Vts map for a set of keys, this is how you can do it:

    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)
    

    Output of the above will be (try it on the Go Playground):

    [d1value d2value]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器