3 回答

TA貢獻1877條經驗 獲得超1個贊
將其解組為類型值interface{}
,并使用類型斷言或類型開關來檢查最終值的類型。請注意,默認情況下,JSON 數組被解組為 type 的值[]interface{}
,因此您必須檢查它以檢測錯誤響應。
例如:
type Response struct {
? ? Message interface{} `json:"message"`
}
func main() {
? ? inputs := []string{
? ? ? ? `{"message":"Message"}`,
? ? ? ? `{"message":["ERROR_CODE"]}`,
? ? }
? ? for _, input := range inputs {
? ? ? ? var r Response
? ? ? ? if err := json.Unmarshal([]byte(input), &r); err != nil {
? ? ? ? ? ? panic(err)
? ? ? ? }
? ? ? ? switch x := r.Message.(type) {
? ? ? ? case string:
? ? ? ? ? ? fmt.Println("Success, message:", x)
? ? ? ? case []interface{}:
? ? ? ? ? ? fmt.Println("Error, code:", x)
? ? ? ? default:
? ? ? ? ? ? fmt.Println("Something else:", x)
? ? ? ? }
? ? }
}
輸出(在Go Playground上嘗試):
Success, message: Message
Error, code: [ERROR_CODE]

TA貢獻1891條經驗 獲得超3個贊
您可以使用自定義類型依次實現json.Unmarshaller并嘗試解碼每種可能的輸入格式:
type Message struct {
? ? Text string
? ? Codes []int
}
func (m *Message) UnmarshalJSON(input []byte) error {
? ? var text string
? ? err := json.Unmarshal(input, &text)
? ? if err == nil {
? ? ? ? m.Text = text
? ? ? ? m.Codes = nil
? ? ? ? return nil
? ? }
? ? var codes []int
? ? err := json.Unmarshal(input, &codes)
? ? if err == nil {
? ? ? ? m.Text = nil
? ? ? ? m.Codes = codes
? ? ? ? return nil
? ? }
? ? return err
}
我更喜歡這種方法,而不是稍后解組interface{}和類型斷言,因為所有類型檢查都封裝在解組步驟中。

TA貢獻1811條經驗 獲得超6個贊
我建議為Message創建一個不同的類型并制作那個實現json.Unmarshaller
這是代碼的樣子
type message struct {
? ? Text? string
? ? Codes []string //or int , assuming array of string as it was not mentioned in the question
}
func (m *message) UnmarshalJSON(input []byte) error {
? ? if len(input) == 0 {
? ? ? ? return nil
? ? }
? ? switch input[0] {
? ? case '"':
? ? ? ? m.Text = strings.Trim(string(input), `"`)
? ? ? ? return nil
? ? case '[':
? ? ? ? return json.Unmarshal(input, &m.Codes)
? ? default:
? ? return fmt.Errorf(`invalid character %q looking for " or [`, input[0])
? ? }
}
type Error struct {
? ? Message message `json:"message"`
}
- 3 回答
- 0 關注
- 205 瀏覽
添加回答
舉報