3 回答

TA貢獻1828條經(jīng)驗 獲得超3個贊
我認為自定義解組功能適用于這種情況
type ErrorServer struct {
Error string
}
type ErrorResponse struct {
ID string
Message string
Status string
}
type ErrorProxy struct {
Err ErrorResponse
}
func parseErrorResponse(body io.Reader) (interface{}, error) {
data := make(map[string]interface{})
if err := json.NewDecoder(body).Decode(&data); err != nil {
return nil, err
}
// Check type of errors field
switch errors := data["errors"].(type) {
case string:
// Unmarshal for ErrorServer
errServer := &ErrorServer{
Error: errors,
}
return errServer, nil
case map[string]interface{}:
// Unmarshal for ErrorProxy
errProxy := &ErrorProxy{
Err: ErrorResponse{
ID: errors["id"].(string),
Message: errors["message"].(string),
Status: errors["status"].(string),
},
}
return errProxy, nil
default:
return nil, fmt.Errorf(`failed to parse "errors" field`)
}
}
func main() {
body := bytes.NewReader([]byte(`{"errors": "failed to ping the dns server."}`))
//body := bytes.NewReader([]byte(`{"errors":{"id": "1", "message": "failed to resolve the ip", "status": "failed"}}`))
parsedErr, _ := parseErrorResponse(body)
switch err := parsedErr.(type) {
case *ErrorServer:
fmt.Printf("err server: %+v \n", err)
case *ErrorProxy:
fmt.Printf("err response: %+v \n", err)
}
}

TA貢獻2011條經(jīng)驗 獲得超2個贊
另一種方法是使用類型斷言。您可以將該 json 字符串解組為map[string]interface{}
并檢查該值interface{}
是 astring
還是map[string]interface{}
。取決于它的類型,您知道它是哪種錯誤并從中構造一個結構。

TA貢獻1850條經(jīng)驗 獲得超11個贊
有趣的是,我只是在這里給出了這個問題的答案:使用自定義UnmarshalJSON函數(shù)。你如何在 Golang 中修改這個結構來接受兩個不同的結果?
適用于您的情況:
package main
import (
"encoding/json"
"fmt"
"log"
)
type Answer struct {
Errors Error `json:"errors"`
}
type ErrorResponse struct {
ID string `json:"id"`
Message string `json:"message"`
Status string `json:"status"`
}
type Error struct {
Error string
ErrorResponse ErrorResponse
}
func (s *Error) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
// no data, nothing to do
return nil
}
if b[0] == '{' {
// is object
return json.Unmarshal(b, &s.ErrorResponse)
}
return json.Unmarshal(b, &s.Error)
}
func main() {
var errProxy = []byte(`{"errors":{"id": "1", "message": "failed to resolve the ip", "status": "failed"}}`)
var errServer = []byte(`{"errors": "failed to ping the dns server."}`)
var answ Answer
if err := json.Unmarshal(errProxy, &answ); err != nil {
log.Fatal(err)
}
fmt.Println(answ)
answ = Answer{}
if err := json.Unmarshal(errServer, &answ); err != nil {
log.Fatal(err)
}
fmt.Println(answ)
}
去游樂場
上面示例中的關鍵是包含兩種變體的類型。我們還可以簡化這一點,因為這兩個錯誤都可以包含在ErrorResponse類型中:
type Answer struct {
Errors ErrorResponse `json:"errors"`
}
type ErrorResponse struct {
ID string
Message string
Status string
}
func (s *ErrorResponse) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
// no data, nothing to do
return nil
}
if b[0] == '{' {
// is object
var tmp struct {
ID string `json:"id"`
Message string `json:"message"`
Status string `json:"status"`
}
if err := json.Unmarshal(b, &tmp); err != nil {
return err
}
s.ID = tmp.ID
s.Message = tmp.Message
s.Status = tmp.Status
return nil
}
return json.Unmarshal(b, &s.Message)
}
Error這里不需要該結構。
- 3 回答
- 0 關注
- 119 瀏覽
添加回答
舉報