codec
codec

Reputation: 8806

Set a global variable only once in golang

I have a main.go file which has:

// running the router in port 9000
func main() {
    router := routers.InitApp()
    router.RunTLS(":9000" , "domain.crt" , "domain.key")
}

In another gofile I have

package utils
var ConfigMap = GetAppConfig
func GetAppConfig() map[string]string{
 ....//
}

ConfigMap being a global variable , everytime I try to access utils.ConfigMap map the GetAppConfig function is called. How can I call this function only once while by app initializes and then access the ConfigMap anyehere I want in the go project.

Upvotes: 15

Views: 35461

Answers (2)

icza
icza

Reputation: 417777

This is what package init() functions are for. They are executed once, before your package can be reached "from the outside":

var ConfigMap map[string]string

func init() {
    // Init ConfigMap here
}

Note that such exported global variables should be protected if you want to allow concurrent use. It would be unfeasible to leave this to the users of the package.

For this purpose, you should declare ConfigMap unexported:

var configMap[string]string

And provide a getter function which would properly protect it with a Mutex:

var confMu = &sync.Mutex{}

func Config(name string) string {
    confMu.Lock()
    defer confMu.Unlock()
    return configMap[name]
}

Upvotes: 22

Arash
Arash

Reputation: 1316

I believe there is a typo in the code that you posted. You define the configMap outside the init function like this:

var configMap map[string]string

This is fine but inside the init you also have this:

var configMap = map[string]string{}

Here you are shadowing the configMap that you have outside the init function meaning that you have declared the variable again inside the init. As a result when you access the variable outside of the init function you will get the global variable which is still empty. If you remove the var inside the init it would work fine.

configMap = map[string]string{}

Here's a quick demonstration.

There is another typo in the original question:

var configMap = GetAppConfig

This should be:

var configMap = GetAppConfig()

You are assigning the function to a variable rather than result of the function.

Upvotes: 1

Related Questions