您现在的位置是:首页 > 文章详情

golang 使用gorequest 遇到的序列化的坑

日期:2018-10-15点击:839

    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) } 

 

原文链接:https://my.oschina.net/u/2950272/blog/2245906
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章