package main
import (
"fmt"
)
const (
cimax uint8 = 255
)
func main() {
var i uint8
var imax uint8 = 255
i = imax << 4
fmt.Printf("%d\n", i)
//i = cimax << 4 // 为什么这里的常量不能正常左移呢?
//fmt.Printf("%d\n", i)
fmt.Printf("%d\n", 0xf0)
}
是不是常量不能作为左移操作法的操作数?
以下是一些不够严谨的分析。
参照文档进行研究,Go必然有这么几个特点:
<<
运算的结果的类型,以左侧操作数为准。而从表象上来看:
对于第1条,如下的代码都会出现同样的错误。对于这两个例子,因为
<<
左侧都是uint8,所以最终的结果也是uint8,则得出的结果装不下uint8就会报错,哪怕最后准备了uint16的容器也不行:对于第2条,如下的代码都可以正确执行:
所以并不是说常量不能作为操作数,而是常量左移之后,Go面对溢出的行为并不是截断而是报错。临时对付这个问题,你可能需要先用不定长度的uint类型绕开溢出的限制,再用掩码(
& 0xFF
)运算去约束结果的范围:更深入的分析期待其他回答者的补充。