为什么字节转换不一致golang?

Jak*_*ard 5 binary byte go bitwise-operators

我有以下示例,取自Addison-Wesley Golang一书,我稍作修改:

package main

import "fmt"

// pc[i] is the population count of i.
var pc [256]byte

func init() {
    for i := range pc {
        pc[i] = pc[i/2] + byte(i&1)
    }
}

// PopCount returns the population count (number of set bits) of x.
func PopCount(x uint64) int {
    fmt.Printf("Value is %d\n", x)
    fmt.Printf("byte(%d>>(0*8)) is %d\n", x, byte(x>>(0*8)))
    y := byte(x>>(0*8))
    return int(pc[y] +
        pc[byte(x>>(1*8))] +
        pc[byte(x>>(2*8))] +
        pc[byte(x>>(3*8))] +
        pc[byte(x>>(4*8))] +
        pc[byte(x>>(5*8))] +
        pc[byte(x>>(6*8))] +
        pc[byte(x>>(7*8))])
}
func main() {
    // fmt.Println(byte(256>>(0*8)))  // This blows up, but doesn't blow up on line 19 or line 20, why?
    fmt.Println(PopCount(256))
}
Run Code Online (Sandbox Code Playgroud)

这里是操场上的相同代码:example-code 为了防止链接过期,这里是操场,你可以粘贴上面的游戏:去游乐场

如果你取消注释

// fmt.Println(byte(256>>(0*8)))
Run Code Online (Sandbox Code Playgroud)

你收到一个错误:

prog.go:31: constant 256 overflows byte
Run Code Online (Sandbox Code Playgroud)

鉴于这是在PopCount中完成而不会爆炸,我不明白发生了什么.当有人在主要但不是在PopCount函数中执行此操作时,有人可以帮助解释为什么它会爆炸吗?

我敢说我错过了一些明显的东西!

Jim*_*imB 4

这是因为256>>(0*8)(相当于256),是一个无类型常量,它太大而无法适应语言规范状态byte中的规则

在以下任何情况下,常量值 x 都可以转换为类型 T:

  • x 由 T 类型的值表示。
  • x 是浮点常量,T 是浮点类型,x 在使用 IEEE 754 舍入到偶数规则舍入后由类型 T 的值表示,但 IEEE -0.0 进一步舍入为无符号 0.0 。常数 T(x) 是四舍五入的值。
  • x 是整数常量,T 是字符串类型。与非常量 x 相同的规则也适用于这种情况。

在函数内部PopCount,该256值的类型为uint64,可以将其转换为 a byte,并将其截断为0