我有一个Go程序,它对字符串常量的长度执行位移和除法运算,但输出不是我所期望的。这是代码:
package main
import "fmt"
const s = "123456789" // len(s) == 9
// len(s) is a constant expression,
// whereas len(s[:]) is not.
var a byte = 1 << len(s) / 128
var b byte = 1 << len(s[:]) / 128
func main() {
fmt.Println(a, b) // outputs: 4 0
}
在此程序中,a 和 b 使用涉及移位和除法的类似表达式计算。然而,a 和 b 的输出分别是 4 和 0,这似乎违反直觉,因为这两个操作都涉及相同的字符串长度和相似的算术。有人能解释一下为什么a和b产生不同的结果吗?
如果您能深入了解这些表达式如何以不同的方式求值以及它们为何会在 Go 中产生不同的输出,我将不胜感激。
第一个示例是常量移位操作,将在“const”空间中执行,结果将转换为
byte
(因为它适合一个字节)。
第二个例子是非常量移位运算,所以根据规范,
1
会先转换为byte
,然后将移位和除法作为byte
值进行(移位结果不适合 byte
,因此结果将是 0
),除以 128
将再次得到 0
。
移位表达式中的右操作数必须具有 整数类型 (Go 1.13) 或者是可由类型
的值表示的无类型常量。如果非常量移位表达式的左操作数是无类型常量,则它首先会隐式转换为移位表达式仅由其左操作数替换时所假定的类型。uint
参见相关:Golang 移位运算符转换