how to create user defined struct for array of different user defined object in golang

huangapple go评论120阅读模式
英文:

how to create user defined struct for array of different user defined object in golang

问题

我正在尝试在Golang中解析JSON对象。

以下是JSON结构:

  1. {
  2. "properties": {
  3. "alertType": "VM_EICAR",
  4. "resourceIdentifiers": [
  5. {
  6. "azureResourceId": "/Microsoft.Compute/virtualMachines/vm1",
  7. "type": "AzureResource"
  8. },
  9. {
  10. "workspaceId": "f419f624-acad-4d89-b86d-f62fa387f019",
  11. "workspaceSubscriptionId": "20ff7fc3-e762-44dd-bd96-b71116dcdc23",
  12. "workspaceResourceGroup": "myRg1",
  13. "agentId": "75724a01-f021-4aa8-9ec2-329792373e6e",
  14. "type": "LogAnalytics"
  15. }
  16. ],
  17. "vendorName": "Microsoft",
  18. "status": "New"
  19. }
  20. }

我有以下自定义类型。

  1. type AzureResourceIdentifier struct {
  2. AzureResourceId string `json:"azureResourceId"`
  3. Type string `json:"type"`
  4. }
  1. type LogAnalyticsIdentifier struct {
  2. AgentId string `json:"agentId"`
  3. Type string `json:"type"`
  4. WorkspaceId string `json:"workspaceId"`
  5. WorkspaceResourceGroup string `json:"workspaceResourceGroup"`
  6. WorkspaceSubscriptionId string `json:"workspaceSubscriptionId"`
  7. }

我有一个顶级的自定义类型作为properties,如下所示。
它有一个resourceIdentifiers字段,是两个其他自定义类型(上面定义的)的数组,

  • AzureResourceIdentifier
  • LogAnalyticsIdentifier

如何定义properties中resourceIdentifiers的类型?

  1. type Properties struct {
  2. AlertType string `json:"alertType"`
  3. ResourceIdentifiers []??? `json:"resourceIdentifiers"`
  4. VendorName string `json:"vendorName"`
  5. Status string `json:"status"`
  6. }

注意:我有一个现有的连接器,我们被授权输入解析JSON的结构体,我们不能覆盖或添加任何函数。

英文:

I am trying to parse json object in golang.

Below is the json structure :

  1. {
  2. "properties": {
  3. "alertType": "VM_EICAR",
  4. "resourceIdentifiers": [{
  5. "azureResourceId": "/Microsoft.Compute/virtualMachines/vm1",
  6. "type": "AzureResource"
  7. },
  8. {
  9. "workspaceId": "f419f624-acad-4d89-b86d-f62fa387f019",
  10. "workspaceSubscriptionId": "20ff7fc3-e762-44dd-bd96-b71116dcdc23",
  11. "workspaceResourceGroup": "myRg1",
  12. "agentId": "75724a01-f021-4aa8-9ec2-329792373e6e",
  13. "type": "LogAnalytics"
  14. }
  15. ],
  16. "vendorName": "Microsoft",
  17. "status": "New"
  18. }
  19. }

I have below user defined types.

  1. type AzureResourceIdentifier struct {
  2. AzureResourceId string `json:"azureResourceId"`
  3. Type string `json:"type"`
  4. }
  1. type LogAnalyticsIdentifier struct{
  2. AgentId string `json:"agentId"`
  3. Type string `json:"type"`
  4. WorkspaceId string `json:"workspaceId"`
  5. WorkspaceResourceGroup string `json:"workspaceResourceGroup"`
  6. WorkspaceSubscriptionId string `json:"workspaceSubscriptionId"`
  7. }

I have a top level user defined type as properties as below.
it has resourceIdentifiers as array of two other user defined types(defined above),

  • AzureResourceIdentifier
  • LogAnalyticsIdentifier

how can I define type of resourceIdentifiers in properties ?

  1. type Properties struct{
  2. alertType string
  3. resourceIdentifiers ??? `
  4. vendorName string `
  5. status string
  6. }

Note: I have a existing connector and we are provisioned to input the struct of the parsing json, we cannot override or add any function.

答案1

得分: 3

这里有几个选项:

  1. []map[string]interface{}
    使用map可以解析数组中的任何JSON对象,但在解析后需要安全地提取信息。

  2. []interface{}
    除非JSON数组中还可以包含非JSON对象元素,否则每个元素在底层都将是一个map。在你的情况下,没有理由使用它而不是map[string]interface{}

  3. 使用覆盖所有可能字段的新结构类型的切片:[]ResourceIdentifier

  1. type ResourceIdentifier struct {
  2. AzureResourceId string `json:"azureResourceId"`
  3. AgentId string `json:"agentId"`
  4. WorkspaceId string `json:"workspaceId"`
  5. WorkspaceResourceGroup string `json:"workspaceResourceGroup"`
  6. WorkspaceSubscriptionId string `json:"workspaceSubscriptionId"`
  7. Type string `json:"type"`
  8. }

这可能是最简单的解决方案。它允许您快速达到目标,但会浪费一些内存,并创建一个不太直观的数据设计,如果以后再次进行序列化可能会引起混淆。

  1. 新的结构类型+自定义的解组实现。
  1. type ResourceIdentifiers struct {
  2. AzureResourceIdentifiers []AzureResourceIdentifier
  3. LogAnalyticsIdentifiers []LogAnalyticsIdentifier
  4. }

实现json.Unmarshaler来决定构造哪种类型的结构以及将其放入哪个切片中。

英文:

There are a couple of options here.

  1. []map[string]interface{}

Using a map will allow any JSON object in the array to be parsed, but burdens you with having to safely extract information after the fact.

  1. []interface{}

Each is going to be a map under the hood, unless non-JSON object elements can also be in the JSON array. No reason to use it over map[string]interface{} in your case.

  1. A slice of a new struct type which covers all possible fields: []ResourceIdentifier
  1. type ResourceIdentifier struct {
  2. AzureResourceId string `json:"azureResourceId"`
  3. AgentId string `json:"agentId"`
  4. WorkspaceId string `json:"workspaceId"`
  5. WorkspaceResourceGroup string `json:"workspaceResourceGroup"`
  6. WorkspaceSubscriptionId string `json:"workspaceSubscriptionId"`
  7. Type string `json:"type"`
  8. }

This is probably the laziest solution. It allows you to get where you want to quickly, at the cost of wasting some memory and creating a non self-explanatory data design which might cause confusion if later trying to serialize with it again.

  1. A new struct type + custom unmarshalling implementation.
  1. type ResourceIdentifiers struct {
  2. AzureResourceIdentifiers []AzureResourceIdentifier
  3. LogAnalyticsIdentifiers []LogAnalyticsIdentifier
  4. }

Implement json.Unmarshaler to decide which type of struct to construct and in which slice to put it.

huangapple
  • 本文由 发表于 2022年2月23日 03:38:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/71227334.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定