【问题标题】:how to create a struct/model in golang with dynamic/arbitrary fields如何在 golang 中使用动态/任意字段创建结构/模型
【发布时间】:2020-09-02 15:44:31
【问题描述】:

是否可以创建具有动态/任意字段和值的结构?

我的应用将收到带有 JSON 正文的请求:

{
"Details": {
  "Id": “123”,
 },
"Event": {
  "Event": "Event",
 },
“RequestValues”: [
  {
    “Name": "Name1",
    "Value": "Val1"
  },
  {
    "Name": "Name2",
    "Value": 2
  },
  {
    "Name": “Foo”,
    "Value": true
  }
    ]
  }

这将被解组到我的模型“请求”:

type Request struct {
    Details         Details          `json:"Details"`
    Event           Event            `json:"Event"`
    RequestValues []RequestValues    `json:"RequestValues"`
}

type Details struct {
    Id     string `json:"Id"`
}

type Event struct {
    Event      string `json:"Event"`
}

type RequestValues struct {
    Name  string `json:"Name"`
    Value string `json:"Value"`
}

我必须将模型“请求”重新映射到具有“值”中任意字段的新模型“事件”。在编组新的重新映射模型“事件”后,我应该得到与请求对应的 JSON 输出:

{
"Event": "Event"
"Values": {
  “Id": "123",      <= non arbitrary mapping from Request.Detail.Id
  "Name1": "Val1",  <= arbitrary 
  "Name2": 2,       <= arbitrary
  “Foo”: true       <= arbitrary
}

}

任意值将从“RequestValues”映射。这些字段的名称应该是 Request.RequestValues.Name 的值,它们的值应该是 Request.RequestValues.Value 的值

这是我的“事件”模型:

type Event struct {
    Event             string `json:"Event"`
    Values            Values `json:"Values"`
}

type Values struct{
    Id      string  `json:"Id"`
}

【问题讨论】:

  • 如果在编译时密钥未知,请使用map[string]interface{}
  • 谢谢彼得,我已经尝试过了,但我一直在努力解决如何准确实现 map[string]interface{} ,请你举个例子说明你将如何在这种情况下做到这一点?
  • 不,因为您没有提供任何开始的代码。不过应该很明显:将 Values 字段现在的任何类型更改为 map[string]interface{}
  • 也许一旦你知道怎么做就很明显了。 @MarcinKulik 如果你展示一些你尝试过的东西,你会得到更好的回应——即使是错误的。回答者可以帮助您了解您的错误所在。
  • 谢谢你们,我已经尝试过更好地描述我的问题。

标签: go struct interface mapping


【解决方案1】:

首先,这是您的 JSON 的有效 JSON 副本:

{
    "Details": {
        "Id": "123"
    },
    "Event": {
        "Event": "Event"
    },
    "RequestValues": [
        {
            "RequestValueName": "Name1",
            "RequestValue": "Val1"
        },
        {
            "RequestValueName": "Name2",
            "RequestValue": 2
        },
        {
            "RequestValueName": "Foo",
            "RequestValue": true
        }
    ]
}

首先创建一个type Input struct{} 来描述您要解析的JSON,并创建一个type Output struct{} 来描述您要生成的JSON,然后编写一些代码来从一个转换到另一个.您不必立即添加所有字段 - 例如,您可以从 Event 开始,然后添加更多字段,直到全部完成为止。

我已在 https://play.golang.org/p/PvpKnFMrJjN 中完成此操作以向您展示,但我建议您先快速阅读一下,然后再尝试自己重新创建它。

将 JSON 转换为 Go 结构的有用工具是 https://mholt.github.io/json-to-go/,但在您的示例中它会触发 RequestValue,它有多种数据类型(因此我们使用 interface{})。

【讨论】:

  • 谢谢@icio,您在 play.golang.org 中的示例对我有用,值应该是 map[string]interface{} 而不是结构
【解决方案2】:

我认为你可以像这样使用地图:

package main

import (
    "fmt"
)

type Event struct {
    event  string
    values map[string]string
}

func main() {
    eventVar := Event{event: "event", values: map[string]string{}}
    eventVar.values["Id"] = "12345"
    eventVar.values["vale1"] = "value"
    fmt.Println(eventVar)
}

您只需要以某种方式验证它所在的 id,如果您需要同一级别的值。

我希望这对你有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 2013-05-29
    • 2015-06-22
    • 1970-01-01
    相关资源
    最近更新 更多