How to create custom unmarshal for 2 types map[string]interface{} and []interface{}

huangapple go评论73阅读模式
英文:

How to create custom unmarshal for 2 types map[string]interface{} and []interface{}

问题

这是我的示例go playground https://go.dev/play/p/MosQs62YPvI

我的curl API返回两种类型的结果,以下是其中之一:

{
  "code": 200,
  "message": "Success",
  "data": {
    "list": {
      "1": {
        "user": "user A",
        "status": "normal"
      },
      "2": {
        "user": "user A",
        "status": "normal"
      }
    },
    "page": 1,
    "total_pages": 2000
  }
}

或者

{
  "code": 200,
  "message": "Success",
  "data": {
    "list": [
      {
        "user": "user A",
        "status": "normal"
      },
      {
        "user": "user B",
        "status": "normal"
      }
    ],
    "page": 1,
    "total_pages": 5000
  }
}

如何正确解组它?

这是我的结构体:

type User struct {
    Code       int `json:"code"`
    Message    string `json:"message"`
    Data       struct {
        List       []struct {
            User    string `json:"user"`
            Status  string `json:"status"`
        } `json:"list"`
        Page       int `json:"page"`
        TotalPages int `json:"total_pages"`
    } `json:"data"`
}

这是我如何解组它的代码:

err := json.Unmarshal([]byte(io_response), &returnData)
if err != nil {
    log.Println(err)
}

我尝试过创建自己的解组函数,但在转换为map[string]interface{}时遇到了问题。你能帮助我吗?或者有更好的方法吗?

英文:

Here's my sample go playground https://go.dev/play/p/MosQs62YPvI

My curl API return 2 kind of return, can any of the ff:

{
  "code": 200,
  "message": "Success",
  "data": {
    "list": {
      "1": {
        "user": "user A",
        "status": "normal"
      },
      "2": {
        "user": "user A",
        "status": "normal"
      }
    },
    "page": 1,
    "total_pages": 2000
  }
}

or

 {
  "code": 200,
  "message": "Success",
  "data": {
    "list": [
      {
        "user": "user A",
        "status": "normal"
      },
      {
        "user": "user B",
        "status": "normal"
      }
    ],
    "page": 1,
    "total_pages": 5000
  }
}

How to unmarshal it properly?

Here's my struct

    type User struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		List []struct {
			User   string `json:"user"`
			Status string `json:"status"`
		} `json:"list"`
		Page       int `json:"page"`
		TotalPages int `json:"total_pages"`
	} `json:"data"`
}

Here's how I unmarshal it

err = json.Unmarshal([]byte(io_response), &returnData)
	if err != nil {
		log.Println(err)
	}

I have tried creating my own unmarshal but I have issues converting it to map[string]interface{}

Can you please help me? Or is there any better way?

答案1

得分: 2

type UserItem struct {
	User   string `json:"user"`
	Status string `json:"status"`
}

type UserList []UserItem

func (ul *UserList) UnmarshalJSON(data []byte) error {
	switch {
	case len(data) == 0 || string(data) == "null":
		return nil
	case data[0] == '[': // 假设它是一个 JSON 数组
		return json.Unmarshal(data, (*[]UserItem)(ul))
	case data[0] == '{': // 假设它是一个 JSON 对象
		obj := make(map[string]UserItem)
		if err := json.Unmarshal(data, &obj); err != nil {
			return err
		}
		for _, v := range obj {
			*ul = append(*ul, v)
		}
		return nil
	default:
		return fmt.Errorf("不支持的 JSON 类型")
	}
	return nil
}

https://go.dev/play/p/Y5PAjrmPhy2

英文:
type UserItem struct {
	User   string `json:"user"`
	Status string `json:"status"`
}

type UserList []UserItem

func (ul *UserList) UnmarshalJSON(data []byte) error {
	switch {
	case len(data) == 0 || string(data) == `null`:
		return nil
	case data[0] == '[': // assume it's a JSON array
		return json.Unmarshal(data, (*[]UserItem)(ul))
	case data[0] == '{': // assume it's a JSON object
		obj := make(map[string]UserItem)
		if err := json.Unmarshal(data, &obj); err != nil {
			return err
		}
		for _, v := range obj {
			*ul = append(*ul, v)
		}
		return nil
	default:
		return fmt.Errorf("unsupported json type")
	}
	return nil
}

https://go.dev/play/p/Y5PAjrmPhy2

huangapple
  • 本文由 发表于 2022年9月30日 12:51:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/73904143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定