背景

有时我们会遇到必须用int64的情景(snowflake id等),这个时候会遇到一个很尴尬的问题,就是js的number类型最大只支持2^53,就会出现精度丢失的情况,这个时候最好是用string与前端交互比较合适。

对于单一的int 序列化为string

type Demo struct {
	ID int64 `json:"id,string"`
}

注意json tag以下的用法:

"json"标签的用法:

1、json:"-":编码的时候会忽略这个字段。

2、json:"newName":指定字段在JSON字符串的key名字。

3、json:"newName,omitempty":如果这个字段是空值,则不编码到JSON里面,否则用newName为名字编码。

4、json:",omitempty":同上,不为空的话,这个字段的key还是用默认的struct字段名。

5、json:",string":编码成字符串,这个string选项只适用字符串,浮点型和整型数据。

struct字段需要可导出才能编码成json,否则会忽略。

将[]int 序列化为[]string

这里就需要用到自定义序列化,也就是实现json/encode 里面的MarshalJson和UnmarshalJson方法。

package main

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

/*
* @Author:hanyajun
* @Date:2019/8/6 10:21
* @Name:json
* @Function:
 */

type IntString int64

type RequestParam struct {
	LoadWaybills []IntString `json:"load_waybills"`
}

func (i IntString) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf("\"%v\"", i)), nil
}

func (i *IntString) UnmarshalJSON(value []byte) error {
	m, err := strconv.ParseInt(string(value[1:len(value)-1]), 10, 32)
	if err != nil {
		return err
	}
	*i = IntString(m)
	return nil
}

func main() {
	var a int64 = 90
	var result = &RequestParam{LoadWaybills: []IntString{IntString(a), 123}}
	b, _ := json.Marshal(result)
	fmt.Printf("marshal result:%s\n", b)
	var result2 RequestParam
	_ = json.Unmarshal(b, &result2)
	fmt.Printf("unmarshal result:%v", result2.LoadWaybills)
}

输出结果

marshal result:{"load_waybills":["123","567"]}
unmarshal result:[90 123]