golang中json的处理

本文探讨了如何在Go语言中正确处理结构体中的数字类型与string类型,包括数字反序列化为float64的处理,以及时间格式在序列化和反序列化中的适配。通过实例展示了json.Marshal和json.Unmarshal的技巧及自定义编码器和解码器的方法。
摘要由CSDN通过智能技术生成

问题1:结构体中数字类型与string类型的处理

package main

import (
	"encoding/json"
	"fmt"
)

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

type Person struct {
	Id  int `json:"id,string"`
	Age int `json:"age,string"`
}

func main() {
	p := Person{
		Id:  12,
		Age: 14,
	}
	marshal, _ := json.Marshal(p)
	fmt.Println(string(marshal))
	s := `{"id":"20","age":"20"}`
	_ = json.Unmarshal([]byte(s), &p)
	fmt.Printf("%#v", p)
}

输出:

{"id":"12","age":"14"}
main.Person{Id:20, Age:20}

问题2:数字类型反序列化后变为float64的处理

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
)

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

func main() {
	m := make(map[string]interface{})
	m["age"] = 1
	marshal, _ := json.Marshal(m)
	fmt.Println(string(marshal))
	s:= `{"age":34}`
	_= json.Unmarshal([]byte(s), &m)
	fmt.Printf("%#v\n",m)
	//⚠️⚠️注意此时的age是float64类型⚠️⚠️
	fmt.Printf("%T\n",m["age"])
	decoder := json.NewDecoder(bytes.NewBuffer([]byte(s)))
	decoder.UseNumber()
	_ = decoder.Decode(&m)
	fmt.Printf("%#v\n",m)
	//打印可以看出此时age是json.Number类型
	fmt.Printf("%T\n",m["age"])
	//⚠️⚠️此处进行断言后调用Int64()方法⚠️⚠️
	i, _ := m["age"].(json.Number).Int64()
	fmt.Printf("%#v\n",i)
	fmt.Printf("%T\n",i)

}

输出:

{"age":1}
map[string]interface {}{"age":34}
float64
map[string]interface {}{"age":"34"}
json.Number
34
int64

问题3:时间格式化的序列化与反序列化的问题

问题原因

package main

import (
	"encoding/json"
	"fmt"
	"time"
)

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

type Person struct {
	Birthday time.Time `json:"birthday"`
}

func main() {
	p := Person{Birthday: time.Now()}
	marshal, _ := json.Marshal(p)
	fmt.Println(string(marshal)) //输出: {"birthday":"2022-02-10T18:05:15.821518+08:00"}

	s := `{"birthday":"2022-02-10 10:00:00"}`
	err := json.Unmarshal([]byte(s), &p)
	//可以看到,对我们习惯对格式化对时间字符串,不是很友好,直接报错了
	fmt.Println(err, p) //输出:parsing time ""2022-02-10 10:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 10:00:00"" as "T" {0001-01-01 00:00:00 +0000 UTC}

}

输出:

{"birthday":"2022-02-10T18:06:41.992661+08:00"}
parsing time ""2022-02-10 10:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 10:00:00"" as "T" {0001-01-01 00:00:00 +0000 UTC}

解决方案:

package main

import (
	"encoding/json"
	"fmt"
	"time"
)

/**
 * @author micro.cloud.fly
 * @date 2022/2/10 5:24 下午
 * @desc
 */

var format = "2006-01-02 15:04:05"

type Student struct {
	Id       int       `json:"id"`
	Birthday time.Time `json:"birthday"`
}

func (stu *Student) MarshalJSON() ([]byte, error) {
	type TmpStudent Student
	ts := struct {
		Birthday string `json:"birthday"`
		*TmpStudent
	}{Birthday: stu.Birthday.Format(format),
		TmpStudent: (*TmpStudent)(stu)}
	return json.Marshal(ts)
}
func (stu *Student) UnmarshalJSON(data []byte) error {
	type TmpStudent Student
	ts := struct {
		Birthday string `json:"birthday"`
		*TmpStudent
	}{Birthday: stu.Birthday.Format(format),
		TmpStudent: (*TmpStudent)(stu)}
	if err := json.Unmarshal(data, &ts); err != nil {
		return err
	}
	var err error
	stu.Birthday, err = time.ParseInLocation(format, ts.Birthday, time.Local)
	return err

}

func main() {
	s := Student{
		Id:       1,
		Birthday: time.Now(),
	}
	//序列化
	marshal, err := json.Marshal(&s)
	fmt.Println(string(marshal), err)

	//-------------------------------
	//反序列化
	str:=`{"birthday":"2022-02-11 10:58:06","id":9999}`
	_ = json.Unmarshal([]byte(str), &s)
	fmt.Printf("s:%#v\n", s)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

micro_cloud_fly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值