“//go:build”和“// +build”指令之间有什么区别?

例如,https://github.com/golang/sys/blob/master/cpu/cpu_gccgo_x86.go#L5:


//go:build (386 || amd64 || amd64p32) && gccgo

// +build 386 amd64 amd64p32

// +build gccgo


package cpu

在我看来,作为一个构建标签,可以很好地工作。

为什么仍然显式指定?// +build ... //go:build


顺便说一句,很难找到的,但很容易(https://pkg.go.dev/cmd/go#hdr-Build_constraints//go:build// +build)


饮歌长啸
浏览 461回答 1
1回答

当年话下

前往 1.18新指令现在是首选,工具链将主动删除旧指令;如 Go 1.18 发行说明中所述://go:build在 Go 1.18 中,现在删除模块中在其 go.mod 文件中声明 go 1.18 或更高版本的过时行。go fix// +build由于上述原因,如果您尝试构建一个 1.17 或更低版本的模块,并且该模块需要 1.18 或更高版本的依赖项,则在缺少依赖项行的情况下,生成可能会失败。go.mod// +build前往 1.17//go:build是用于指定生成约束的新条件编译指令。它是在 Go 1.17 中引入的。它旨在取代旧的指令;用例仍然是相同的:它“列出了文件应包含在包中的条件”。新语法带来了一些关键改进:// +build与其他现有 Go 指令和编译指示的一致性,例如//go:generate支持标准布尔表达式,例如,而旧注释的语法不那么直观。例如,AND 用逗号表示,用 OR 用空格表示//go:build foo && bar// +build// +build foo,bar// +build foo bar它受 支持,它将自动修复指令在源文件中的错误位置,从而避免常见错误,因为在指令和包语句之间不会留下空行。go fmt这两个构建指令将在几个Go版本中共存,以确保平稳过渡,如相关提案文档中所述(在下面的引文中,N是17,强调我的):Go 1.N将开始过渡。在 Go 1.N 中:生成将开始首选行以进行文件选择。如果文件中没有,则任何行仍然适用。//go:build//go:build// +build如果 Go 文件包含 不 带 的 生成将不再失败。//go:build// +build如果 Go 或程序集文件包含的文件中太晚,则生成将失败。Gofmt 会将错放的 //go:构建和 // +构建行移动到它们在文件中的正确位置。//go:buildGofmt将使用与其他 Go 布尔表达式相同的规则(all 和运算符周围的空格)将表达式格式化为行。//go:build&&||如果文件只包含 // +构建行,gofmt 将在它们上方添加等效的 //go:构建行。如果文件同时包含 //go:构建和 // +构建行,gofmt 将考虑 //go:build 真实来源并更新行以匹配,从而保持与早期版本的 Go 的兼容性。 还将拒绝被认为过于复杂而无法转换为格式的行,尽管这种情况很少见。(请注意此项目符号开头的“如果”。 不会向只有 .) 的文件添加行。// +buildGofmt//go:build// +buildGofmt// +build//go:build签入将添加对约束的支持。当 Go 源文件包含具有不同含义的 //go:构建和 // +构建行时,它将失败。如果检查失败,可以运行 。buildtagsgo vet//go:buildgofmt -w当 Go 源文件包含 without 并且其包含模块具有列出 Go 1.N 之前版本的 go 行时,检查也将失败。如果检查失败,可以添加任何行,然后运行 ,这将用正确的行替换它。或者可以将 go 版本提升到 Go 1.N。buildtags//go:build// +build// +buildgofmt -wgo.mod有关语法更改的详细信息:Golang 条件编译
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go