Go单个字节(byte)转字符串(string)的一点坑

最近遇到一个小问题,由于某个api只支持写入string,而我生成的压缩后的数据都是一个字节的byte,所以不得不将byte转成string。于是写出了如下的代码:

1
s := string(b) // b is byte

这样只要b在0000000011111111之间,编译是不会报任何问题的,随便写了几个ut也没有问题,于是提交了代码。
等到部署后发现,数据量比预估的大了很多,于是仔细review代码,发现问题只可能出在byte转string的时候。多写了几个测试用例后发现,当单个byte转string时,如果byte的值大于127,那么转换出来的string就会占用两个字节。
比如127转string,长度为1,但把128转string的时候,长度就为2了:

1
2
3
var b byte = 128
s := string(b)
fmt.Println(len(s)) // Print 2

究其原因,可能是由于127是ASCII码的最大值,而128已经到了扩展ASCII码表,Go语言不知道为什么会对扩展ASCII码里的单个byte转string的时候解析出两个字节的string。要规避这种神奇的转换也很简单,那就是先将单个byte转成数组,再转成string:

1
s := string([]byte{b})

这样转出来就一点问题都没有了,也是很神奇。

分享到