The Go Programming Language book,练习6.5,作者告诉我们使用这个表达式:
32 << (^uint(0) >> 63)
检查平台是32位还是64位。
表达式非常清楚,我们可以使用简单的代码检查结果:
package main
import "fmt"
func main() {
fmt.Println(32 << (^uint(0) >> 63))
}
代码在32位平台上打印0
,在64位平台上打印64
。
但是,对文件使用go vet
,我会收到警告:
$ go vet ex6-5.go
ex6-5.go:6: ^uint(0) might be too small for shift of 63
exit status 1
为什么go vet
会向我显示警告?我该如何预防?
答案 0 :(得分:2)
这是因为uint
不是固定的按位长度类型,它可能短到32位,所以不足以让你右移63。
这也是您可以使用此表达式测试平台的原因,因为uint
将采用平台上最高效的int
类型。
如果在32位平台上,uint
的长度为32位,那么右移将提供0
,这导致32
最终成为{32 << 0
的结果1}}。但是在64位平台上,uint
给出了64位,因此右移63位会给你1
而不是0
,最终导致64
由于32 << 1
提供64
。
看一下兽医的源代码:
71 case types.Int, types.Uint, types.Uintptr:
72 // These types may be as small as 32 bits, but no smaller.
73 size = 32
74 msg = "might be "
...
78 if amt >= size {
79 ident := f.gofmt(x)
80 f.Badf(node.Pos(), "%s %stoo small for shift of %d", ident, msg, amt)
81 }
也就是说,只要您使用uint并右移63位,go vet
检查shift
,就无法逃脱检查。你可以尝试通过提供要检查的标志来跳过它:
go tool vet -shift=false yourfile.go
答案 1 :(得分:1)
为什么去看兽医告诉我这个警告?我该如何预防?
nevets的答案提出:
你可以尝试通过提供要检查的标志来跳过它:
go tool vet -shift=false yourfile.go
但是:你不应该使用go tool vet
。只有1个}}。或者在这种情况下,只是因为你需要传递一个标志。
然而,从1.10开始(2018年第一季度),这将改变:见this thread:
请勿使用“
go vet
”,这对于go tool vet
的工作人员基本上只有用处(就像您通常不会运行“vet
一样“)。以前您需要使用“
go tool compile
”,如果您想控制兽医旗帜,但“go tool vet
”现在接受“go vet
”所有的标志。 (参见“go tool vet
”。)
所以go help vet
就足够了。