3

I'm trying to extend a map across packages at 'compile time'. Is this possible?

I have package A with a predefined map:

package A

var MyMap = map[string]string{"key1": "value", "key2": "value"}

And I would like to extend the map during 'compile time'. This shall be done in another package. E.g. like so (not working code ofc.):

package B

import "A"

A.MyMap.Slice1["key3"] = "value" // extend the map during compile time

Is this somehow possible?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
xsigndll
  • 513
  • 1
  • 5
  • 13

3 Answers3

4

You can't do this "at compile" time. In fact, the composite literal that package A uses, that also will be constructed and used at runtime. There are no composite literal constants.

Going further, whatever code you write in package B, if it imports package A, code of package B will only run after package A has been initialized, including the map you posted.

If you want A.MyMap to have a different value before it can be seen by any other package, you should modify the source of package A. This could be a generated additional file, which could use a package init() function, assigning a new value to MyMap, or adding new values to it.

If you can, you could also modify package A so that the initialization of MyMap is moved to a different source file, one that can be generated.

icza
  • 389,944
  • 63
  • 907
  • 827
  • Meaning the map of `package A` will be constructed upon first interaction with the package? Or at import? – xsigndll Feb 04 '19 at 22:03
  • Package `A` will be initialized before any other package could reference anything from it. – icza Feb 04 '19 at 22:04
2

It is actually extension at runtime but it should fit your example.

Use init function.

package B

import "A"

func init() {
    A.MyMap["key3"] = "value"
}
Grzegorz Żur
  • 47,257
  • 14
  • 109
  • 105
  • 1
    That one is working ofc. I intentionally need it at compile time :-/ I tried init() but failed to have this one being called without the package actually being imported. I guess I'll have to find a way around it somehow. – xsigndll Feb 04 '19 at 21:57
2

You pass a string at linking time with command

go build -ldflags '-X somemap={"k":"v"}'

and then parse it to map at run time. You can easily use JSON format.

See more on GcToolchainTricks.

Grzegorz Żur
  • 47,257
  • 14
  • 109
  • 105