为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
九州编程 2023-04-17 15:59:14
我这里有一个(非)工作示例: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{ },但我不确定您是否可以将模型定义为列表?
查看完整描述

2 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

看起来您正在尝试访问嵌套在根“设置”属性下的“条件”属性。因此,您需要定义该根级类型和足够的字段来告诉解组器如何找到您的目标属性。因此,您只需要创建一个带有必要的“设置/条件”字段的新“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",

//   },

// }


查看完整回答
反对 回复 2023-04-17
?
HUX布斯

TA贡献1876条经验 获得超6个赞

这是一种替代方法,它围绕结构方法进行访问,数据结构也已完全定义。

package main


import (

    "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))


}


查看完整回答
反对 回复 2023-04-17
  • 2 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信