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

就是这样!


更多文章
  • 读《远见-如何规划职业生涯3大阶段》
  • 后端工程师学前端(五): SASS
  • 后端工程师学前端(四): CSS进阶(盒子模型)
  • 读《投资中最简单的事》
  • 后端工程师学前端(三): CSS进阶(特指度、单位和字体族)
  • 后端工程师学前端(二): CSS基础知识(规则与选择器)
  • Swift语法笔记
  • 读《管理的实践》
  • 后端工程师学前端(一): HTML
  • frp 源码阅读与分析(二):TCP内网穿透的实现
  • 五天不用微信 - 爽得很
  • frp 源码阅读与分析(一):流程和概念
  • 学习frp源码之简洁的在两个connection之间转发流量
  • 自己动手写一个反向代理
  • 读《债务危机》