今天在调试索引色图片的时候,使用golang碰到一个很奇怪的事情, 代码如下:
var pal_data []byte //调色板数据
var img_data []byte //图像数据
new_img := image.NewRGBA(image.Rect(0, 0, Width, Height))
for x:=0; x < len(img_data); x++ {
v := img_data[x]
if(v == 106) {
vv:=106
fmt.Println("V1=",v,",C={",pal_data[vv*3+2],",",pal_data[vv*3+1], ",",pal_data[vv*3], "}")
fmt.Println("V2=",v,",C={",pal_data[v*3+2],",",pal_data[v*3+1], ",",pal_data[v*3], "}")
}
}
[/sourcecode]
<p> 我特别提取了一个索引值106,结果发现打印出来的颜色值是不同的,使用vv这个指定变量的值是正确的, 另外一个却是错误的。 </p>
<p> 我一开始以为是优化的问题,然后取消了所有优化,发现结果还是不同的。 </p>
<p> 程序没有任何警告之类的,除了结果是错误的,其他的都正常。 </p>
<p> 直到我修改成下面的样子: </p>
v := img_data[x]*3
if(v == 106*3)
在其他语言中,最多会有个警告,在golang中,直接报错了:
constant 318 overflows byte
…. 使用golang 的语法糖果然是需要代价的,当v:=img_data[x]的时候,v的类型是byte,标示范围为 0-255,然后v*3还是个byte,计算结果标示的范围还是0-255,并不会自动转换为容量更大的short或者int, 所以计算到最后还是个byte, 远远没办法访问所有的调色板数据了。
所以将v:=img_data[x]修改喂v:=int(img_data[x])就没问题了
类型很重要,当使用简单写法的时候尤其需要注意。