Leave a comment (3) 作者:adwin

其实这个问题发现了有好多天了,今天没什么事就写出来。

长话短说,就是给定一个byte变量,赋予一个128以上的值,转换成字符串类型,一般来说这是一个不可见字符,但将这个字符转换为[]byte的slice(slice是GO中的一种类型,可以理解为可变长的数组)的时候,会在前边多出一个十六进制是0xC2的不可见字符,ASCII值是194。我曾一度以为这是一个BUG。

举个栗子:

点击查看原图

这个栗子里,我给byte型变量s赋值129(大于128),转换为字符串,按说这个字符串里应该是只有一个字符,并且这个字符是不可见的,可当我把这个字符串变量再次转换为byte数组(严格的来说是slice)的时候,前边就多出了一个元素,值是194。经过测试,只要是大于16进制0x80,十进制128,的字符,都会出现这个问题。

关于这个问题是如何出现的我一直不能理解,所以甚至一度以为这是一个BUG,但是很显然GO不可能在经历这么多个版本之后会出现这种低级的BUG,所以我也没有去深究类型转换的底层代码是如何写的,直到偶然间看到一段类型转换的代码,终于将这其中的原由有了了解。

话不多说,上个代码就什么都解释清楚了。

 

func int2byte(x int) byte {
    y := int32(x)
    b_buf := bytes.NewBuffer([]byte{})
    binary.Write(b_buf, binary.BigEndian, y)
    z := b_buf.Bytes()[3] //int32转成byte后是一个4个元素的数组,根据需求这里只取最后一个元素
    return z //所以传过来的int值不能大于一个十六进制所能表达的最大数,也就是0xFF/255,否则不准确啊
}

 

人家GO压根就是这么设计的。。。但这绝对是个坑!要不是及时抓包发现,指不定还得多久才能发现呢!因为0xC2是一个不可见字符啊,如果你打在控制台上的话根本看不到!
分类:GO | 标签: 编程 GO
分享到:

评论列表:

Niwda
2016-03-04 14:47
Adwin 果然不愧是名不虚传 .....
注册公司
2016-11-07 12:52
这样可以抓出来,很厉害。
大刀
2019-05-29 15:44

不使用byte,而是直接使用[]byte则没有问题。
b := make([]byte,1)
b[0] = 129
s := string(b)
再转为[]byte输出就是 [129]

我也说两句 »