golang 类型转换的陷阱

今天在调试索引色图片的时候,使用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&#91;x&#93;
  if(v == 106) {
    vv:=106
    fmt.Println("V1=",v,",C={",pal_data&#91;vv*3+2&#93;,",",pal_data&#91;vv*3+1&#93;, ",",pal_data&#91;vv*3&#93;, "}")
    fmt.Println("V2=",v,",C={",pal_data&#91;v*3+2&#93;,",",pal_data&#91;v*3+1&#93;, ",",pal_data&#91;v*3&#93;, "}")
  }
}

&#91;/sourcecode&#93;

<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])就没问题了

类型很重要,当使用简单写法的时候尤其需要注意。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据