Is there a way to define a constant at build time in Go?
Asked Answered
H

2

13

I have a program in Go that I want to compile in a bunch of binaries, each having a const value defined differently. More clearly, I have something like that:

const wordLen = 6
type knowledge [wordLen]byte

Here, wordLen is associated with the value 6, but I want to have different binaries, with values ranging from 5 to 10. I could make it a variable, and then use a slice rather than an array, but that would have a huge performance impact on my soft (yes, I tried).

I would love to have some build tag on go build argument to indicate what the value of wordLen is for a given binary. So, what is the (as idiomatic as possible) way to do this ?

Haemophilia answered 22/3, 2016 at 10:2 Comment(0)
S
25

Yes, this is possible using Build Constraints.

You can supply a list of these constraints to go build using the -tags flag.

Example:

main.go

package main

import "fmt"

func main() {
    fmt.Println(f)
}

foo.go

// +build foo

package main

const f = "defined in foo.go"

bar.go

// +build bar

package main

const f = "defined in bar.go"

Compiling the code with different tags will give different results:

$ go build -tags foo
$ ./main
defined in foo.go
$ go build -tags bar
$ ./main
defined in bar.go
Sydelle answered 22/3, 2016 at 10:21 Comment(1)
and what if I just run go build? Will the build end with an error complaining about undefined symbol f? How can I provide a kind of defaults to use when neither -tags bar, nor -tags foo is specified?Mesa
S
16

It doesn't solve your exact problem but it may solve others so I add for completeness that you can use the -ldflags option of the go compiler:

go build -ldflags "-X main.wordLen=6"

Its however has two downsides:

  • Only works for strings
  • Only works on vars
Sawyor answered 22/3, 2016 at 10:26 Comment(1)
Those are huge downsides since I need to use a numeric constant ;) However, this is a very useful functionality in some contexts.Haemophilia

© 2022 - 2024 — McMap. All rights reserved.