Go中的C样式巨集

I've been playing with go for a week and something I miss from C is preprocessor macros.

What could I use to get this feature, besides hacking a build script that pipes go files through clang -E ?

As mentioned in the comments, build flags are probably the best way to solve whatever you need. For example, if you wanted to have some features only available in development, use a dev flag:

File constants_dev.go:

// +build dev
const DEVELOPMENT = true

File constants_pro.go

// +build !dev
const DEVELOPMENT = false

Then in your code, just do a simple if DEVELOPMENT { blah... }. I find this much more readable than any preprocessor. This can get quite messy if you have a lot of build flags, but at that point you should probably be using command-line arguments instead.

In your comment, you mentioned duplication of code. If your code is really that repetitive, you should probably be putting it in a function anyway, or possibly restructure code to reuse the bits that are repetitive. Personally, I find that anything beyond simple boolean checks ends in hard to maintain code, especially with C-style macros.

It's the same thing with generics. In one Java library I've used, the class signature was something like this:

class Thing<A, B, C, D, E>

The library wasn't very well documented, so I had to read a significant amount of the code (both implementation and code that uses the library) to understand what was going on.

In Go, the language forces a style that generally leads to better, self-documenting code. I think the Go developers omitted things like a preprocessor and generics to avoid temptation to write hard to maintain, but clever, code.

I would advise you to try out the Go way before looking back on old idioms that you used before. I think you'll find that most of what macros and #defines were used for are largely irrelevant.

I think cpp, m4 or whatever may fulfill your desire to have Go preprocessed. If it's a good idea or not is a decision of yours, but be warned that any preprocessing is a substantial obstacle for adoption of any published Go code. (And for example, the build being dependent on makefiles is the same story.)