Go里优雅的使用全局配置
全局配置是一个单例,最简单的实现是使用一个全局变量,为了到处都可以使用到,所以常见的做法是有一个包,例如名字叫 global
或者诸如此类的,然后要用到的地方去导入,例如:
package handlers
import (
"log"
"github.com/jiajunhuang/demo/global"
)
func Ping() {
log.Printf("%s", global.Config.RedisURL)
}
不过这样写起来挺麻烦的,所以,不如这样写。首先咱们照样有一个包,叫做 singleton
,里面就有 Config
的单例方法:
package singleton
import (
"sync"
"github.com/kelseyhightower/envconfig"
)
var (
config *Config
configMutex sync.Mutex
)
type Config struct {
Debug bool `envconfig:"debug"`
DBURL string `envconfig:"db_url"`
}
func GetConfig() *Config {
if config != nil {
return config
}
configMutex.Lock()
defer configMutex.Unlock()
// double check
if config != nil {
return config
}
config = &Config{}
envconfig.Process("APP_NAME", config)
return config
}
于是,咱们就可以这样使用了:
package main
import (
"github.com/jiajunhuang/demo/singleton"
)
func main() {
// init config
_ = singleton.GetConfig()
}
在别的包里,可以这样:
package handlers
import (
"github.com/jiajunhuang/demo/singleton"
)
var (
config = singleton.GetConfig()
)
func Haha() {
println(config.DBURL)
}
若要问我区别,其实没啥太大的区别,只不过呢,写起来更简单了,只要写 config.Blabla
而不是 global.Config.Blabla
。
就是这样!