问题
javascript
中能安全表示的数字范围在
而后端用的是int64
int64的范围是:
然后就会出现如此神器的现象
解决方法
字符串大法好
在结构体可能出现问题的字段加上json
的tag,
type D struct {
ID int64 `json:"id,string"`
Name string
}
这样就会在序列化的时候自动由int64
转为string
,反序列化的时候自动由string
转为int64
(或者说,一个较为麻烦的方法:自己定义一个Marshal, UnMarshal
自己实现int64
和string
互转的过程)
demo如下:
type D struct {
ID int64 `json:"id,string"`
Name string `json:"name"`
}
func main() {
d := &D{
ID: math.MaxInt64,
Name: "xiaos",
}
// json 序列化
p, err := json.Marshal(d)
if err != nil {
return
}
fmt.Println(string(p))
// 反序列化json
s := `{"ID":"9223372036854775807","Name":"xiaos"}`
var d2 D
if err := json.Unmarshal([]byte(s), &d2); err != nil {
fmt.Println(err)
}
fmt.Println(d2)
}
奇技淫巧
忽略字段
在tag中添加-
// 使用tag指定json序列化与反序列化时的行为
type Person struct {
Name string `json:"name"` // 指定json序列化/反序列化时使用小写name
Age int64
Gender string `json:"-"` // 指定json序列化/反序列化时忽略此字段
}
忽略空值字段
在对应字段添加omitempty tag
来忽略空值字段
// 在tag中添加omitempty忽略空值
// 注意这里 hobby,omitempty 合起来是json tag值,中间用英文逗号分隔
type User struct {
Name string `json:"name"`
Email string `json:"email,omitempty"`
Address []string `json:"address,omitempty"`
}
处理不确定层级的json
如果json串没有固定层级或格式,不好解析,可以使用json.RawMessage
原始字节数据保存下来。
type sendMsg struct {
User string `json:"user"`
Msg string `json:"msg"`
}
func rawMessageDemo() {
//jsonStr := `{"data":{"user":"xs","msg":"一点一点往上爬"},"print":"Hello"}`
jsonStr := `{"data":{"user":"xs","msg":"一点一点往上爬"},"print":"Hello"}`
// 定义一个map,value类型为json.RawMessage,方便后续灵活地处理
var data map[string]json.RawMessage
if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
fmt.Printf("json.Unmarshal jsonStr failed, err:%v\n", err)
return
}
var msg sendMsg
if err := json.Unmarshal(data["data"], &msg); err != nil {
fmt.Printf("json.Unmarshal failed, err:%v\n", err)
return
}
fmt.Printf("msg:%#v\n", msg)
// msg:main.sendMsg{User:"xs", Msg:"一点一点往上爬"}
}
func main() {
rawMessageDemo()
}