Заполнить структуру динамически из параметров - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть следующая структура, которая работает, как ожидалось, я получаю данные и я смог

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 поля (user / id / address), но некоторые службы (service1) могут предоставлять дополнительные данные, такие как электронная почта, secondName и т. Д. но большая проблема здесь в том, что Мне нужно получить его по параметрам, поскольку (услуга 2) образование, зарплата и т. Д.

Сервис2

{
    "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[]), но я не знаю их заранее, это должно быть динамически как-то .... есть хороший способ справиться с этим на Голанге?

1 Ответ

0 голосов
/ 12 ноября 2018

Если вы не знаете полей заранее, то не используйте структуру, но что-то, что также является «динамическим»: карту.

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...