亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何取消封送一個JSON字段,該字段要么是結構體,要么是結構體數組?

如何取消封送一個JSON字段,該字段要么是結構體,要么是結構體數組?

Go
慕沐林林 2022-09-19 17:24:58
用例我有一個API,在其中我將用戶輸入作為對象或對象數組接收。喜歡這個:不帶數組的 JSON{  "sign": {    "page_no": 1,    "x_coord": 100,    "y_coord": 300  }}帶有數組的 JSON{  "sign": [    {      "page_no": 1,      "x_coord": 100,      "y_coord": 300    },    {      "page_no": 2,      "x_coord": 200,      "y_coord": 400    }  ]}結構到昂馬沙爾到type Document struct {  Sign []Sign `json:"sign"` // or just Sign}type Sign struct {  PageNo int `json:"page_no"`  XCoord int `json:"x_coord"`  YCoord int `json:"y_coord"`}由于遺留的原因,我無法將上的字段作為所有用戶輸入的數組,因此它需要既是數組又只是。SignDocumentSignSign如何取消封送,以便它可以處理下面的兩個JSON請求?我知道那件事。。。我們可以使用而不是結構,但這會導致太多的關鍵斷言,當我使用結構時,您不必這樣做,因為我可以為它們利用零值。map[string]interface{}另外,這個答案在堆棧溢出似乎沒問題,但我想知道有沒有更好的方法來做到這一點?
查看完整描述

3 回答

?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

使用自定義 json 取消封口方法創建切片類型。然后,在該解編中,您可以檢測您擁有的輸入類型,并相應地執行操作。此方法在我的視頻 Go 中的高級 JSON 處理中進一步詳細說明。

type Signs []Sign


func (s *Signs) UnmarshalJSON(d []byte) error {

    if d[0] == '{' {

        // We know it's a single object

        var v Sign

        err := json.Unmarshal(d, &v)

        *s = Signs{v}

        return err

    }

    // Otherwise it's an array

    var v []Sign

    err := json.Unmarshal(d, &v)

    *s = Signs(v)

    return err

}


查看完整回答
反對 回復 2022-09-19
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

可以通過實現自定義取消封口程序,在完全沒有(或類型斷言)的情況下執行此操作。我會通過窺視JSON內部并檢查它是否以方括號或大括號開頭來實現取消元帥...跳過空格。interface{}

請參閱 json。文檔中的解封接口。

type Document struct {

    Sign SignList

}


type SignList []Sign


func (l *SignList) UnmarshalJSON(d []byte) error {

    for _, b := range d {

        switch b {

        // These are the only valid whitespace in a JSON object.

        case ' ', '\n', '\r', '\t':

        case '[':

            return json.Unmarshal(d, (*[]Sign)(l))

        case '{':

            var obj Sign

            if err := json.Unmarshal(d, &obj); err != nil {

                return err

            }

            *l = []Sign{obj}

            return nil

        default:

            return errors.New("sign must be object or list")

        }

    }

    return errors.New("sign must be object or list")

}

這似乎有點笨拙。哦,好吧。除了編碼/json 之外,還有用于 Go 的替代 JSON 取消編組庫。如果您愿意,請嘗試使用替代的 JSON 庫。此代碼僅適用于編碼/json。


下面介紹如何測試此代碼是否正常工作:


package main


import (

    "fmt"

    "encoding/json"

    "errors"

)


type Sign struct {

    X int

}


func main() {

    cases := []string {

        `{"Sign": {"X": 1}}`,

        `{"Sign": [{"X": 1}, {"X": 2}]}`,

    }

    for _, c := range cases {

        var doc Document

        if err := json.Unmarshal([]byte(c), &doc); err != nil {

            fmt.Println("Error:", err)

            continue

        }

        fmt.Printf("Document: %+v\n", &doc)

    }

}

打印如下:


Document: &{Sign:[{X:1}]}

Document: &{Sign:[{X:1} {X:2}]}


查看完整回答
反對 回復 2022-09-19
?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

實現一個可以驗證數據的類型進行測試,并將其用作檢查。


例如:


package main


type SignTest struct {

    Sign map[string]interface{} `json:"sign"`

}


func main() {

    s := `{

  "sign": [

    {

      "page_no": 1,

      "x_coord": 100,

      "y_coord": 300

    },

    {

      "page_no": 2,

      "x_coord": 200,

      "y_coord": 400

    }

  ]

}`


    err := json.Unmarshal([]byte(s), &SignTest{})


    if err != nil {

        fmt.Println("Document Type")

    } else {

        fmt.Println("Sign Type")

    }

}

打印 ,而Document Type


package main



type SignTest struct {

    Sign map[string]interface{} `json:"sign"`

}


func main() {

    s := `{

  "sign": {

    "page_no": 1,

    "x_coord": 100,

    "y_coord": 300

  }

}`


    err := json.Unmarshal([]byte(s), &SignTest{})


    if err != nil {

        fmt.Println("Document Type")

    } else {

        fmt.Println("Sign Type")

    }

}

指紋。Sign Type


但是,在取消編組符號以外的對象是否是數組時,這里可能會出錯,如果您想要更安全,請檢查錯誤的錯誤消息,該錯誤應按預期方式假設為 。Document


查看完整回答
反對 回復 2022-09-19
  • 3 回答
  • 0 關注
  • 123 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號