为什么不能将此数据正确解组到我的对象模型中?

我这里有一个(非)工作示例:https ://play.golang.org/p/qaYhKvJ65J3

我不确定为什么会出现以下数据:

alertData := `{

    "Id": 0,

    "Version": 0,

    "OrgId": 1,

    "DashboardId": 61,

    "PanelId": 84,

    "Name": "{qa-dev}{stats-pipeline} Topology Message Age (aggregator) alert",

    "Message": "",

    "Severity": "",

    "State": "",

    "Handler": 1,

    "Silenced": false,

    "ExecutionError": "",

    "Frequency": 10,

    "EvalData": null,

    "NewStateDate": "0001-01-01T00:00:00Z",

    "PrevStateDate": "0001-01-01T00:00:00Z",

    "StateChanges": 0,

    "Created": "0001-01-01T00:00:00Z",

    "Updated": "0001-01-01T00:00:00Z",

    "Settings": {

        "conditions": [

            {

                "evaluator": {

                    "params": [

                        10000

                    ],

                    "type": "gt"

                },

                "operator": {

                    "type": "and"

                },

                "query": {

                    "datasourceId": 2,

                    "model": {

                        "hide": true,

                        "refCount": 0,

                        "refId": "C",

                        "textEditor": false

                    },

                    "params": [

                        "C",

                        "5m",

                        "now"

                    ]

                },

                "reducer": {

                    "params": [],

                    "type": "avg"

                },

                "type": "query"

            }

        ],

        "executionErrorState": "keep_state",

        "frequency": "10s",

        "handler": 1,

        "name": "{qa-dev}{stats-pipeline} Topology Message Age (aggregator) alert",

        "noDataState": "keep_state",

        "notifications": []

    }

}`

我只是得到:json object:::: {Evaluator:{Params:[] Type:} Operator:{Type:} Query:{Params:[]} Reducer:{Params:[] Type:} Type:}


理想情况下,我能够将其解析为类似的东西type Conditions []struct{ },但我不确定您是否可以将模型定义为列表?


九州编程
浏览 99回答 2
2回答

慕码人8056858

看起来您正在尝试访问嵌套在根“设置”属性下的“条件”属性。因此,您需要定义该根级类型和足够的字段来告诉解组器如何找到您的目标属性。因此,您只需要创建一个带有必要的“设置/条件”字段的新“AlertData”类型。例如:type AlertData struct {  Settings struct {    Conditions []Condition `json:"conditions"`  }}func main() {  alert := AlertData{}  err := json.Unmarshal([]byte(alertData), &alert)  if err != nil {    panic(err)  }  fmt.Printf("OK: conditions=%#v\n", alert.Settings.Conditions)  // OK: conditions=[]main.Condition{main.Condition{Evaluator:struct { Params []int "json:\"params\""; Type string "json:\"type\"" }{Params:[]int{10000}, Type:"gt"}, Operator:struct { Type string "json:\"type\"" }{Type:"and"}, Query:struct { Params []string "json:\"params\"" }{Params:[]string{"C", "5m", "now"}}, Reducer:struct { Params []interface {} "json:\"params\""; Type string "json:\"type\"" }{Params:[]interface {}{}, Type:"avg"}, Type:"query"}}}请注意,打印的列表包含如此多的类型信息,因为“条件”类型使用匿名结构作为字段类型。如果您要将它们提取到命名结构中,那么使用数据会更容易,例如:type Condition struct {  Evaluator Evaluator `json:"evaluator"`  Operator  Operator  `json:"operator"`  // ...}type Evaluator struct {  Params []int  `json:"params"`  Type   string `json:"type"`}type Operator struct {  Type string `json:"type"`}//...// OK: conditions=[]main.Condition{//   main.Condition{//     Evaluator:main.Evaluator{Params:[]int{10000}, Type:"gt"},//     Operator:main.Operator{Type:"and"},//     Query:main.Query{Params:[]string{"C", "5m", "now"}},//     Reducer:main.Reducer{Params:[]interface {}{}, Type:"avg"},//     Type:"query",//   },// }

HUX布斯

这是一种替代方法,它围绕结构方法进行访问,数据结构也已完全定义。package mainimport (    "encoding/json"    "fmt"    "log"    "time")type Data struct {    ID             int         `json:"Id"`    Version        int         `json:"Version"`    OrgID          int         `json:"OrgId"`    DashboardID    int         `json:"DashboardId"`    PanelID        int         `json:"PanelId"`    Name           string      `json:"Name"`    Message        string      `json:"Message"`    Severity       string      `json:"Severity"`    State          string      `json:"State"`    Handler        int         `json:"Handler"`    Silenced       bool        `json:"Silenced"`    ExecutionError string      `json:"ExecutionError"`    Frequency      int         `json:"Frequency"`    EvalData       interface{} `json:"EvalData"`    NewStateDate   time.Time   `json:"NewStateDate"`    PrevStateDate  time.Time   `json:"PrevStateDate"`    StateChanges   int         `json:"StateChanges"`    Created        time.Time   `json:"Created"`    Updated        time.Time   `json:"Updated"`    Settings       struct {        Conditions          []Condition   `json:"conditions"`        ExecutionErrorState string        `json:"executionErrorState"`        Frequency           string        `json:"frequency"`        Handler             int           `json:"handler"`        Name                string        `json:"name"`        NoDataState         string        `json:"noDataState"`        Notifications       []interface{} `json:"notifications"`    } `json:"Settings"`}type Condition struct {    Evaluator struct {        Params []int  `json:"params"`        Type   string `json:"type"`    } `json:"evaluator"`    Operator struct {        Type string `json:"type"`    } `json:"operator"`    Query struct {        DatasourceID int `json:"datasourceId"`        Model        struct {            Hide       bool   `json:"hide"`            RefCount   int    `json:"refCount"`            RefID      string `json:"refId"`            TextEditor bool   `json:"textEditor"`        } `json:"model"`        Params []string `json:"params"`    } `json:"query"`    Reducer struct {        Params []interface{} `json:"params"`        Type   string        `json:"type"`    } `json:"reducer"`    Type string `json:"type"`}func (d Data) GetFirstCondition() (Condition, error) {    if len(d.Settings.Conditions) > 0 {        return d.Settings.Conditions[0], nil    }    return Condition{}, fmt.Errorf("no conditions found")}func (d Data) GetConditionByIndex(index uint) (Condition, error) {    if len(d.Settings.Conditions) == 0 {        return Condition{}, fmt.Errorf("no conditions found")    }    if int(index) > len(d.Settings.Conditions)-1 {        return Condition{}, fmt.Errorf("index out of bounds")    }    return d.Settings.Conditions[index], nil}var alertData = `{    "Id": 0,    "Version": 0,    "OrgId": 1,    "DashboardId": 61,    "PanelId": 84,    "Name": "{qa-dev}{stats-pipeline} Topology Message Age (aggregator) alert",    "Message": "",    "Severity": "",    "State": "",    "Handler": 1,    "Silenced": false,    "ExecutionError": "",    "Frequency": 10,    "EvalData": null,    "NewStateDate": "0001-01-01T00:00:00Z",    "PrevStateDate": "0001-01-01T00:00:00Z",    "StateChanges": 0,    "Created": "0001-01-01T00:00:00Z",    "Updated": "0001-01-01T00:00:00Z",    "Settings": {        "conditions": [            {                "evaluator": {                    "params": [                        10000                    ],                    "type": "gt"                },                "operator": {                    "type": "and"                },                "query": {                    "datasourceId": 2,                    "model": {                        "hide": true,                        "refCount": 0,                        "refId": "C",                        "textEditor": false                    },                    "params": [                        "C",                        "5m",                        "now"                    ]                },                "reducer": {                    "params": [],                    "type": "avg"                },                "type": "query"            }        ],        "executionErrorState": "keep_state",        "frequency": "10s",        "handler": 1,        "name": "{qa-dev}{stats-pipeline} Topology Message Age (aggregator) alert",        "noDataState": "keep_state",        "notifications": []    }}`func main() {    var res Data    err := json.Unmarshal([]byte(alertData), &res)    if err != nil {        log.Fatal(err)    }    fmt.Println(res.GetFirstCondition())    fmt.Println(res.GetConditionByIndex(0))    // should fail :-)    fmt.Println(res.GetConditionByIndex(1))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go