51

我在 Go 1 中遇到了条件编译问题。

这是我的测试代码。我对“// +build”约束和“-tags”标志有什么误解吗?

main1.go

// +build main1
package main

import (
    "fmt"
)

func main() {
    fmt.Println("This is main 1")
}

main2.go

// +build main2
package main

import (
    "fmt"
)

func main() {
    fmt.Println("This is main 2")
}

运行“go build”时,仍然出现编译错误

$ go build -tags 'main1'
# test
./main2.go:8: main redeclared in this block
        previous declaration at ./main1.go:8
4

5 回答 5

76

您必须在后面// +build XXX加上一个空行。

在我的简短搜索中,我找不到在哪里/是否记录了这一点。但消息来源明确指出

于 2012-05-18T09:00:43.370 回答
12

对,你必须留一个空行,不是正好在之后// +build XXX而是之前,package main因为声明包的行之前的所有注释行都被认为是包的描述,并由godoc.

于 2012-12-02T21:18:04.637 回答
12

包构建

构建约束

构建约束是一个以指令开头的行注释,该指令 +build列出了文件应包含在包中的条件。约束可以出现在任何类型的源文件中(不仅仅是 Go),但它们必须出现在文件顶部附近,前面只能有空行和其他行注释。

为了将构建约束与包文档区分开来,一系列构建约束必须后跟一个空行。

在构建约束后添加一个空行。例如,

// +build main1

package main

import (
    "fmt"
)

func main() {
    fmt.Println("This is main 1")
}
于 2013-06-16T15:59:10.200 回答
11

从 Go 1.17 开始,条件构建标签能够使用//go:build支持布尔表达式的行而不是旧// +build行。

主要改进

  • //go:build注释格式与其他 go 指令一致,如//go:embed, //go:generate,//go:noinline等。
  • 构建标签之间的布尔表达式的语法现在已经标准化,使用&&||运算符

语法比较

表达 // +build //go:build
或者 // +build foo bar(空格分隔) //go:build foo || bar
// +build foo,bar //go:build foo && bar
非(不变) // +build !foo //go:build !foo

多行注释

更复杂的布尔表达式可以使用括号,而在它之前需要多行注释:

从:

// +build foo bar
// +build 386

到:

//go:build (foo || bar) && 386

此外,//go:build现在不允许使用超过一行的多个指令。

自动格式化

此外,go fmt在带有// +build指令的源文件上运行将自动添加匹配//go:build的。

如果文件只包含 // +build 行,gofmt 将在它们上方添加一个等效的 //go:build 行。


资料来源:Go 1.17 构建约束草案设计。(即使 Go 1.17 正式发布,目前仍然是一个草案)

于 2021-06-11T12:42:16.080 回答
4

构建约束文档:

为了将构建约束与包文档区分开来,一系列构建约束必须后跟一个空行。

于 2013-05-23T05:26:28.330 回答