【问题标题】:C-style conditional compilation in golanggolang 中的 C 风格条件编译
【发布时间】:2016-12-21 09:54:04
【问题描述】:

golang 支持吗

#define DEBUG 

#ifdef DEBUG 
  fmt.Println("Debug message..."); 
#endif 

所以我可以构建一个运行时开销为零的调试版本?

【问题讨论】:

  • 严格来说没有。没有预处理器,因此没有预处理器魔法。
  • 像 Java 中一样,GoLang 中没有任何嵌入式预处理器,但也像 Java 一样,可以使用 3th side 类似的工具。例如我使用Java Comment Preprocessor + mvn-golang,效果很好

标签: go conditional-compilation


【解决方案1】:

Go 没有预处理器或宏系统。您可以做的是传递标签以通过 -tags 标志进行构建并使用构建约束。为此,您需要相同源的两个版本,并且根据标签是否存在,只构建一个版本。

查看https://golang.org/pkg/go/build/中的构建约束

main_debug.go

// +build debug

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Debug build")
}

main_release.go

// +build !debug

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Release build")
}

这里 go build 将使用 main_release.go 编译,go build -tags debug 将使用 main_debug.go 编译

【讨论】:

  • 如果不明显。您可以在这些文件中将常量声明为 true 或 false,因为它们是互斥的。然后,您可以在 if 语句中使用该常量。 Go 将根据构建标签识别 if 语句始终为真或假,并从非调试构建中删除代码,反之亦然。
  • @JohnLeidegren 谈论的一个例子can be found here
【解决方案2】:

如果你在 linuxMac 上工作,你可以试试“m4”命令。这个命令是一个宏 处理器正好适合这个问题。

在“go build”之前编写一个 Makefile 来运行 m4 命令可以与使用“go build -tags ...”做同样的事情,并且支持更多的自定义,当然,节省您的工作。

例如:

将这些写在你的 go 文件中(例如 main.go):

define(DEBUG)
ifdef(`DEBUG',
    fmt.Println("Debug message..."); 
)

将这些写入您的 Makefile 文件中:

all:*.go
    mv main.go main.go.bak
    m4 main.go.bak > main.go
    go build
    mv main.go.bak main.go

然后运行“make”。

缺点:

  1. 您不能编写名为“define”或“ifndef”等的 go 函数,这些函数将由 m4 翻译成宏。
  2. 如果您有很多文件,您可能需要改进您的 Makefile。
  3. 您可能想学习有点困难和复杂的m4。

【讨论】:

  • 这是我一直想做的事情,但使其不切实际的主要缺点是 linter 不理解 m4 并且会非常困惑。编写没有任何 linter 提供实时反馈的代码显然是可能的,但相当不愉快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
相关资源
最近更新 更多