背景
有时我们会遇到必须用int64的情景(snowflake id等),这个时候会遇到一个很尴尬的问题,就是js的number类型最大只支持2^53,就会出现精度丢失的情况,这个时候最好是用string与前端交互比较合适。
对于单一的int 序列化为string
1 2 3
| type Demo struct { ID int64 `json:"id,string"` }
|
-
注意json tag以下的用法:
1、json:"-"
:编码的时候会忽略这个字段。
2、json:"newName"
:指定字段在JSON字符串的key名字。
3、json:"newName,omitempty"
:如果这个字段是空值,则不编码到JSON里面,否则用newName为名字编码。
4、json:",omitempty"
:同上,不为空的话,这个字段的key还是用默认的struct字段名。
5、json:",string"
:编码成字符串,这个string选项只适用字符串,浮点型和整型数据。
6、struct字段需要可导出才能编码成json,否则会忽略。
将[]int 序列化为[]string
这里就需要用到自定义序列化,也就是实现json/encode 里面的MarshalJson和UnmarshalJson方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package main
import ( "encoding/json" "fmt" "strconv" )
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) }
|
1 2
| marshal result:{"load_waybills":["123","567"]} unmarshal result:{[123 567]}
|