Golang出现匪夷所思的[]uint8自动转换成string的问题

发布于 2020-06-06 01:06:13 阅读 99

问题

1591376876904.jpg

如图所示,这是我定义的一个结构体,其中一个字段是[]uint8类型,后面会把数组赋值给这个PlatformArr字段

WX20200606-011031@2x.png

其中我预期返回的结果是

platform_arr = [1,2]

但是在输出的json中,却输出了字符串AQI=

WX20200606-011932@2x.png

我当时一脸懵逼,怎么会输出了字符串,如果是空数组我也可以接受,但是字符串我是接受不了的。

排查问题

于是我通过debug的方式一步一步的将代码走下去,代码都没问题,但是就是输出的时候会将数组转换成字符串,我很是纳闷。

于是我将这个字段的[]uint8换成了[]bool, 此时代码却正确返回了空数组。

我猜是不是因为json的序列话把我的uint8改成了其他的值?因为请求结束后,代码会以json的方式输出

WX20200611-202738@2x.png

下面我们来写一个简单demo,来验证猜想

    var res []byte
    res = append(res, 1)
    res = append(res, 2)
    re,_ := json.Marshal(res)
    fmt.Println(string(re))

执行后,竟然打印出来了AQI=

1591878663453.jpg

现在就可以确定的确是由于json.Marshal导致的[]uint8转换成了string

继续追查之

通过代码的追踪,找到在切片中,byte单独做了处理

WX20200611-203411@2x.png

而我们的byteuint8的别名

WX20200606-012412@2x.png

在后续的encodeByteSlice函数中,此函数对字符换进行了base64 encode操作。

在demo中进行测试

var res []byte
    res = append(res, 1)
    res = append(res, 2)
    fmt.Println(base64.StdEncoding.EncodeToString(res))
    fmt.Println("-=-=-=-=-=--=-")

WX20200611-203840@2x.png

可以看到,确实输出了出问题的字符串。

总结

由于go内置的json官方库在使用uint8(byte)切片时会在内部将切片进行base64的操作,会导致预期的效果与实际的结果不一致,所以我们只要将定义的[]uint8改成[]uint类型即可。