问题
如图所示,这是我定义的一个结构体,其中一个字段是[]uint8
类型,后面会把数组赋值给这个PlatformArr
字段
其中我预期返回的结果是
platform_arr = [1,2]
但是在输出的json中,却输出了字符串AQI=
我当时一脸懵逼,怎么会输出了字符串,如果是空数组我也可以接受,但是字符串我是接受不了的。
排查问题
于是我通过debug的方式一步一步的将代码走下去,代码都没问题,但是就是输出的时候会将数组转换成字符串,我很是纳闷。
于是我将这个字段的[]uint8
换成了[]bool
, 此时代码却正确返回了空数组。
我猜是不是因为json的序列话把我的uint8改成了其他的值?因为请求结束后,代码会以json的方式输出
下面我们来写一个简单demo,来验证猜想
var res []byte
res = append(res, 1)
res = append(res, 2)
re,_ := json.Marshal(res)
fmt.Println(string(re))
执行后,竟然打印出来了AQI=
现在就可以确定的确是由于json.Marshal
导致的[]uint8
转换成了string
。
继续追查之
通过代码的追踪,找到在切片中,byte
单独做了处理
而我们的byte
是uint8
的别名
在后续的encodeByteSlice
函数中,此函数对字符换进行了base64 encode
操作。
在demo中进行测试
var res []byte
res = append(res, 1)
res = append(res, 2)
fmt.Println(base64.StdEncoding.EncodeToString(res))
fmt.Println("-=-=-=-=-=--=-")
可以看到,确实输出了出问题的字符串。
总结
由于go内置的json
官方库在使用uint8(byte)
切片时会在内部将切片进行base64
的操作,会导致预期的效果与实际的结果不一致,所以我们只要将定义的[]uint8
改成[]uint
类型即可。