golang 序列化的库没其他语言那么好用,然后就掉坑里了。
 
    是用gorequest 库发现的,这个高start 的库,还是有些问题。我使用场景是这样的:
 
package main
import (
	"fmt"
	"github.com/parnurzeal/gorequest"
)
type InStruct struct {
	Param float64
}
func main() {
	postData := InStruct{Param: int64(72057594088097496)}
	resp, bodyBytes, errs := gorequest.New().Get("http://127.0.0.1:8080").Query(postData).EndBytes()
	fmt.Println(resp, bodyBytes, errs)
}
 
    然后,我发送的数据变成了:Param=72057594088097500。相当于是数据被四舍五入了,一番追查,发现底层做了这个操作,把数据给变了:
 
func (s *SuperAgent) queryStruct(content interface{}) *SuperAgent {
	if marshalContent, err := json.Marshal(content); err != nil {
		s.Errors = append(s.Errors, err)
	} else {
		var val map[string]interface{}
		if err := json.Unmarshal(marshalContent, &val); err != nil {// 这里就会丢精度
			s.Errors = append(s.Errors, err)
		} else {
			for k, v := range val {
				k = strings.ToLower(k)
				var queryVal string
				switch t := v.(type) {
				case string:
					queryVal = t
				case float64:
					queryVal = strconv.FormatFloat(t, 'f', -1, 64)
				case time.Time:
					queryVal = t.Format(time.RFC3339)
				default:
					j, err := json.Marshal(v)
					if err != nil {
						continue
					}
					queryVal = string(j)
				}
				s.QueryData.Add(k, queryVal)
			}
		}
	}
	return s
}
 
    换句话说,就是讲数据由map[string]int64 变成map[string]interface{}, 然后,数据发生了变化。
 
    json 在处理go的数据类型转换时,有个对应关系:
 
 
  
   
   | 数据类型 | JSON | Golang | 
 
  
  
   
   | 字串 | string | string | 
 
   
   | 整数 | number | int64 | 
 
   
   | 浮点数 | number | flaot64 | 
 
   
   | 数组 | arrary | slice | 
 
   
   | 对象 | object | struct | 
 
   
   | 布尔 | bool | bool | 
 
   
   | 空值 | null | nil | 
 
  
 
     在将数字类型unmarshal 转化为interface{} 的时候,默认会先使用浮点数转换,这样,可能会丢失精度。那如何处理?反序列化的时候,将数据类型转换为json.Number 就ok,这样数据会延迟转换,后面可以根据需要转换为int64 或者是 float ,也可以是string。
 
    给个正确的例子,应该使用UseNumber 反序列化:
 
package main
import (
	"bytes"
	"encoding/json"
	"fmt"
)
type Account struct {
	Email    string `json:"email"`
	Password string `json:"password"`
	Money    int64  `json:"money"`
}
func main() {
	account := Account{
		Email:    "137311107@qq.com",
		Password: "123",
		Money:    int64(72057594088097496),
	}
	deal(account)
}
func deal(data interface{}) {
	bdata, err := json.Marshal(data)
	fmt.Printf("err %v, str %+v\n", err, string(bdata))
	var val map[string]interface{}
	d := json.NewDecoder(bytes.NewBuffer(bdata))
	d.UseNumber()
	err = d.Decode(&val)
	fmt.Printf("err %v, str %+v\n", err, val)
}