【发布时间】:2021-01-13 10:44:12
【问题描述】:
我有 3 个文件。一个main 和另外两个normal gokrazy 应该根据构建约束交替构建。两者都在init() 期间从main 更新全局变量。 normal是
// +build !gokrazy
package main
import "fmt"
func init() {
foo = "normal"
fmt.Println("init:", foo)
}
另一个gokrazy是:
// +build gokrazy
package main
import "fmt"
func init() {
foo = "gokrazy"
fmt.Println("init:", foo)
}
go vet *.go 很高兴。当我运行 go run *.go 时,我看到 BOTH 初始化函数被调用:
init: gokrazy
init: normal
我希望只有一个被叫到。 go list 确认选择了预期的文件,但是我仍然看到两个初始化函数。 Golang Build Constraints Random 解释说可能需要强制编译,但这不会改变结果:
❯ go list -f '{{.GoFiles}}' -tags=gokrazy -a && go run -tags=gokrazy -a *.go
[gokrazy.go main.go]
init: gokrazy
init: normal
为什么否定的!gokrazy构建标签不生效?
【问题讨论】:
-
永远不要使用带有文件名参数的 go run!实际上永远不要使用 go run! 绝不!特别是没有 build 标签:构建标签是用于构建的,你可以通过它们的名字来判断。
go run只是忽略构建标签(这是 go run 的唯一合理用例:执行从构建中排除的帮助脚本)。go vet *.go也是错误的:go 工具适用于包而不是文件。从您的工具集中使用 go vet 和 go build 和 drop go run。
标签: go