我正在嘗試在 golang 中決議 json 物件。
下面是json結構:
{
"properties": {
"alertType": "VM_EICAR",
"resourceIdentifiers": [{
"azureResourceId": "/Microsoft.Compute/virtualMachines/vm1",
"type": "AzureResource"
},
{
"workspaceId": "f419f624-acad-4d89-b86d-f62fa387f019",
"workspaceSubscriptionId": "20ff7fc3-e762-44dd-bd96-b71116dcdc23",
"workspaceResourceGroup": "myRg1",
"agentId": "75724a01-f021-4aa8-9ec2-329792373e6e",
"type": "LogAnalytics"
}
],
"vendorName": "Microsoft",
"status": "New"
}
}
我有以下用戶定義的型別。
type AzureResourceIdentifier struct {
AzureResourceId string `json:"azureResourceId"`
Type string `json:"type"`
}
type LogAnalyticsIdentifier struct{
AgentId string `json:"agentId"`
Type string `json:"type"`
WorkspaceId string `json:"workspaceId"`
WorkspaceResourceGroup string `json:"workspaceResourceGroup"`
WorkspaceSubscriptionId string `json:"workspaceSubscriptionId"`
}
我有一個頂級用戶定義型別作為屬性,如下所示。它有 resourceIdentifiers 作為另外兩個用戶定義型別的陣列(上面定義),
- Azure資源識別符號
- 日志分析識別符號
如何在屬性中定義資源識別符號的型別?
type Properties struct{
alertType string
resourceIdentifiers ??? `
vendorName string `
status string
}
注意:我有一個現有的連接器,我們被配置為輸入決議 json 的結構,我們不能覆寫或添加任何函式。
uj5u.com熱心網友回復:
這里有幾個選項。
[]map[string]interface{}
使用映射將允許決議陣列中的任何 JSON 物件,但會增加您必須在事后安全提取資訊的負擔。
[]interface{}
除非非 JSON 物件元素也可以在 JSON 陣列中,否則每個都將是底層的映射。沒有理由map[string]interface{}在你的情況下使用它。
- 覆寫所有可能欄位的新結構型別的切片:
[]ResourceIdentifier
type ResourceIdentifier struct {
AzureResourceId string `json:"azureResourceId"`
AgentId string `json:"agentId"`
WorkspaceId string `json:"workspaceId"`
WorkspaceResourceGroup string `json:"workspaceResourceGroup"`
WorkspaceSubscriptionId string `json:"workspaceSubscriptionId"`
Type string `json:"type"`
}
這可能是最懶惰的解決方案。它允許您快速到達您想要的位置,但代價是浪費一些記憶體并創建一個不言自明的資料設計,如果以后再次嘗試使用它進行序列化,可能會導致混亂。
- 一種新的介面型別 自定義解組實作。
type ResourceIdentifier interface {}
使用自定義介面表示可能存在自定義解組邏輯。該介面實際上不需要任何方法。事實上,這對我們有利,因為我們可以直接解組一次,然后“優化”包含的欄位。
func (properties *Properties) UnmarshalJSON(data []byte) error {
err := json.Unmarshal(data, properties)
if err != nil {
return err
}
for i := 0; i < len(properties.ResourceIdentifiers); i {
resourceIdentifier, ok := properties.ResourceIdentifiers[i].(map[string]interface)
if !ok {
return fmt.Errorf("non-JSON object in []ResourceIdentifiers")
}
// TODO:
// 1. Marshal resourceIdentifier again
// 2. Switch-statement on resourceIdentifier["Type"]
// - Get concrete value by unmarshaling into it.
// - Set value of properties.ResourceIdentifiers[i] to concrete value.
}
return nil
}
使用結果的代碼仍然需要進行型別斷言;沒有明智的解決辦法。如果沒有別的,這是一個很好的鍛煉。如果可能的話,我會嘗試將 JSON 格式更改為不首先在 JSON 陣列中混合型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/431205.html
下一篇:從json中提取c#物件
