2016-2-26 21:01 FridayGO语言的坑之字节和字符串间转换
其实这个问题发现了有好多天了,今天没什么事就写出来。
长话短说,就是给定一个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是一个不可见字符啊,如果你打在控制台上的话根本看不到!