使用了太长时间的python,对于强类型的Golang适应起来稍微有点费力,不过操作一次之后发现,只有这么严格的类型规定,才能让数据尽量减少在传输和解析过程中的错误。我尝试使用Golang创建了一个公司的OpenAPI的demo,记录一下中间遇到的问题。

编码(Encode)Json:

首先来看下如何将字典编码成Json:

// 首先使用字面量来申明和初始化一个字典
param := map[string]int{"page_no": 1, "page_size": 40}
paramJson, err := json.Marshal(param)

使用json.Marshal接收需要json.encode的变量。而json.Marshal接收的是interface{}接口变量,该接口变量可以接收任何类型的数据。

[]byte转String以及String转[]byte:

通常我在python里面使用json.dumps来对字典进行序列化的时候,我通常认为出来的值是一个string,可以将其作为string进行操作。但是这里很明显返回的不是字符串(string)类型,而是一个[]byte类型。所以如果有需要,我们可以将[]byte类型,转换回string进行操作。这里有几种方法可供选择:

直接使用:
string([]byte) 或使用:
String([]byte[:])

ps:现在这两个得到的结果会是一样的,我现在使用的版本是1.8。1.8以前好像会是不同的表现。

同时我们也会遇到想要将string转换回[]byte的时候。方法如下:

[]byte(string)

Http包的post请求来实践对Json的序列化反序列化:

当我们把json编码好之后我们需要将信息传递给服务器。所以用到了http包。

在使用了之后我觉得go的http包真的非常方便,的确如传言中描述的强大和人性化,方便实用。

resp , err := http.PostForm(requestUrl, url.Values{"api_key": {ApiKey}, "api_sign": {apiSign},
"param": {string(param)}, "time": {now_time}, "version": {version}})

这里我使用http.PostForm方法使用带参数传递的post方法请求服务器。url.Values后面可以跟key[string][]string的形式传递参数。返回一个http.response结构体指针和一个error类型。

http.response具体带有哪些属性可以详细查看一下包,这里我们会去解析他的Body字段,里面存储着返回的内容:

// The Body is automatically dechunked if the server replied
// with a "chunked" Transfer-Encoding.
Body io.ReadCloser

这里Body是一个有io.ReadCloser接口的值。io.ReadCloser接口实现了Read()和Write()方法。

我会用json的Decoder去解析它:

var response openApiResponse
resp := request.RequestHeader(paramJson, version, SyncUrl)
err1 := json.NewDecoder(resp.Body).Decode(&response)
if err1 != nil {
log.Println(err1)
}
return resp

这里json.NewDecoder接收一个有Reader方法的变量,之后我们调用了Decoder的方法decode将里面的内容都存入事先申请好的response结构体变量中。这个变量初始化了我们通过文档了解到的返回的结构体字段类型。

openApiResponse struct {
Success bool `json:"success"`
ResultCode int `json:"result_code"`
ResultMsg string `json:"result_msg"`
// 接收JSON字段
Result GoodsSyncResult `json:"result"`
}

这样一级一级解析下去,在构造接收返回回来数据的结构体的时候,注意到后面的json字段。他是一个tag,可以在解析json的时候将对应名字的tag解析到对应的变量中。

这样就相当于你做好了数据结构,然后将对应的数据放到对应的字段里面去。

当然还有一种办法,当你不知道你所接收数据的数据结构的时候,你是没有办法提前申明好这些数据结构然后来接收的。这时我们可以申明一个空接口interface{},让空接口的指针来接收这组数据,可以查看这组数据的数据结构。

var hahaha interface{}
resp := request.RequestHeader(paramJson, version, SyncUrl)
err1 := json.NewDecoder(resp.Body).Decode(&hahaha)
if err1 != nil {
log.Println(err1)
}

上面的hahaha可以接收并decodejson,来接收这组数据。并且可以直接使用fmt.Print之类函数直接打印接收到的数据。如果想直接使用,我们可以使用类型断言但是更推荐的方法是,我们可以根据这组数据来写对应的结构体,然后将数据接收到结构体上进行操作。就像上面一样。

同样的我们还可以使用一个map[string]interface{}来接收这个Json以方便对其进行后续操作,避免不需要的多余的反射。

var hahaha map[string]interface{}
resp := request.RequestHeader(paramJson, version, SyncUrl)
err1 := json.NewDecoder(resp.Body).Decode(&hahaha)
return hahaha

除了实现一个decoder来处理数据,我们往往有Json序列化之后就立即需要序列化的操作,这个同样很容易使用:

json.Unmarshal([]byte, &xx)

来处理就好了。参数一是需要decode的Json数据, 参数二是用于接收这组数据的结构体字段。同样的我们也可以使用一个空接口来接收数据,也可以使用一一对应的结构体来放置数据。

看了上面的一堆介绍有一个感觉,就处理Json数据和类型转换来说。。python真是简单到爆炸,一个dumps一个loads轻松搞定。但是Golang严格的参数类型缺可以保证解析过来的数据一定是对应的数据结构和数据类型。不会在类型上报错更为严谨。个人觉得这很有趣,也很喜欢。

Reference:

http://stackoverflow.com/questions/3371714/go-string-to-ascii-byte-array  go-string-to-ascii-byte-array

http://stackoverflow.com/questions/24377907/golang-issue-with-accessing-nested-json-array-after-unmarshalling  golang-issue-with-accessing-nested-json-array-after-unmarshalling

http://blog.csdn.net/tiaotiaoyly/article/details/38942311  在Go语言中使用JSON

Golang的Json encode/decode以及[]byte和string的转换的更多相关文章

  1. Java - byte[] 和 String互相转换

    通过用例学习Java中的byte数组和String互相转换,这种转换可能在很多情况需要,比如IO操作,生成加密hash码等等. 除非觉得必要,否则不要将它们互相转换,他们分别代表了不同的数据,专门服务 ...

  2. C# Byte[] 转String 无损转换

    C# Byte[] 转String 无损转换 转载请注明出处 http://www.cnblogs.com/Huerye/ /// <summary> /// string 转成byte[ ...

  3. [转]关于网络通信,byte[]和String的转换问题

    最近的项目中要使用到把byte[]类型转换成String字符串然后通过网络发送,但发现发现出去的字符串和获取的字符串虽然是一样的,但当用String的getBytes()的方法得到的byte[]跟原来 ...

  4. JSON和Map,List,String互相转换

    1)Map 和 JSON 互相转换 Map 转成 JSON Map<String, List> map = new HashMap<>(); map.put("xAx ...

  5. C#中byte[]与string的转换

    1.        System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();        byte[] i ...

  6. golang []byte和string的高性能转换

    golang []byte和string的高性能转换 在fasthttp的最佳实践中有这么一句话: Avoid conversion between []byte and string, since ...

  7. C#图像处理:Stream 与 byte[] 相互转换,byte[]与string,Stream 与 File 相互转换等

    C# Stream 和 byte[] 之间的转换 一. 二进制转换成图片 MemoryStream ms = new MemoryStream(bytes); ms.Position = 0; Ima ...

  8. golang的json操作

    package main import ( "encoding/json" "fmt" "os" ) type ConfigStruct s ...

  9. node_nibbler:自定义Base32/base64 encode/decode库

    https://github.com/mattrobenolt/node_nibbler 可以将本源码复制到自己需要的JS文件中,比如下面这个文件,一个基于BASE64加密请求参数的REST工具: [ ...

随机推荐

  1. UVA12545-Bits Equalizer(思维)

    Problem UVA12545-Bits Equalizer Accept: 821  Submit: 4548Time Limit: 3000 mSec Problem Description I ...

  2. SpringBoot注册登录(三):注册--验证账号密码是否符合格式及后台完成注册功能

    SpringBoot注册登录(一):User表的设计点击打开链接SpringBoot注册登录(二):注册---验证码kaptcha的实现点击打开链接      SpringBoot注册登录(三):注册 ...

  3. php面试中的经典问题

    原文:https://blog.csdn.net/ghostlv/article/details/51284745 问题一问题描述考虑下面代码: $str1 = 'yabadabadoo';$str2 ...

  4. 【vue】vue +element 搭建及开发中项目中,遇到的错误提示

    1. import Layout from '@/views/layout/Layout'; export default [ { // 配置路由,当路径为'/activePublic',使用组件ac ...

  5. memcache讲解和在.net中初使用

    memcache讲解和在.net中初使用 2017年10月17日 22:51:36 等待临界 阅读数:503   前言 传统数据库面临的问题 数据库死锁 磁盘IO 正文 了解memcache 原理 基 ...

  6. Troubleshooting ORA-12547 TNS: Lost Contact (Doc ID 555565.1)

    Troubleshooting ORA-12547 TNS: Lost Contact (Doc ID 555565.1) This error can occur in following scen ...

  7. Node.js读取文件内容并返回值(非异步)

    主要解决的问题的,以最近VsCode插件开发为例,每次请求都需要token,而vscode并不支持cookie这样的存储,所以就采用粗暴点办法,存到某个用户目录下并读取. 源码如下: var fs=r ...

  8. Scala--模式匹配和样例类

    模式匹配应用场景:switch语句,类型查询,析构,样例类 一.更好的switch val ch :Char = '+' val sign = ch match{ case '+' => 1 c ...

  9. DIY——自制吸烟仪

    起因: 计划开始学电路相关知识,学习过程肯定离不开电烙铁,毕竟是在家弄,烟雾味道太大而且有毒.去某宝上搜一搜,一个吸烟仪动辄就得80 90米,就一个风扇一根管子一个壳子这个价格太贵了. 正好之前主机上 ...

  10. 正确理解CAP定理

    前言 CAP的理解我也看了很多书籍,也看了不少同行的博文,基本每个人的理解都不一样,而布鲁尔教授得定义又太过的简单,没有具体描述和场景案例分析.因此自己参考部分资料梳理了一篇与大家互相分享一下. 标题 ...