在Go语言中,如何将参数配置化

发布于:2025-09-13 ⋅ 阅读:(21) ⋅ 点赞:(0)

如何将参数配置化

在实习过程中,遇到一个很常见的需求,那就是将一些变量值可以通过配置导入

比如下面这个原本写死的变量:

const (
	ListeningAddress = "0.0.0.0:18888"
	RealPoolAddress = "127.0.0.1:3333"
)

实现思路

1.肯定是先写一个结构体来存这个配置值

type Config struct {
	ListeningAddress string `yaml:"listening_address" json:"listening_address"`
	RealPoolAddress string `yaml:"real_pool_address" json:"real_pool_address"`
}

那么我原本既然是写死的一个值,那肯定代表我默认情况下是这样的值,那必然下一步思路是设置一个默认值,于是:

2.配置一个默认值

func DefaultConfig() *Config{
    return &Config{
        ListeningAddress: "0.0.0.0:18888",
		RealPoolAddress:  "127.0.0.1:3333",
    }
}

有了默认值,下一步必然就是,通过配置文件加载,于是:

3.加载配置

下面就是实现LoadConfig

按照优先级:命令行>配置文件>默认值。所以:

func LoadConfig()(*Config,error){
    // 1. 默认配置
    config := DefualtConfig()
    // 2. 加载配置文件
    ...
    // 3. 加载命令行
    ...
}

所以下面依次简单实现loadFromFileloadFromFlags方法,对应配置文件命令行

func loadFromFile(config *Config, filename string) err{
    if _,err := os.state(filename); os.IsNotExist(err){return err}

    // 解析
    data,err:= os.ReadFile(filename)
    if err!=nil{return err}

    ext:= strings.ToLower(filepath.Ext(filename))
    switch ext{
        case ".yaml",".yml" : return yaml.Unmarshal(data,config)
        default: return yaml.Unmarshal(data,config)
    }
}
func loadFromFlags(config *Config) {
    listenAddr := flag.String("listen",config.ListeningAddress,"listening address")
    poolAddr := flag.String("pool",config.RealPoolAddress,"real pool address")

    // 解析命令行
    flag.Parse()

    // 更新配置
	if *listeningAddr != config.ListeningAddress {
		config.ListeningAddress = *listeningAddr
	}
	if *poolAddr != config.RealPoolAddress {
		config.RealPoolAddress = *poolAddr
	}
}

4.方便使用的一些工具方法

先声明一个配置接口:

// Config 配置接口,用于获取地址参数
type Config interface {
	GetListeningAddress() string
	GetRealPoolAddress() string
}

为Config结构体实现该接口:

// GetListeningAddress 获取监听地址
func (c *Config) GetListeningAddress() string {
	return c.ListeningAddress
}

// GetRealPoolAddress 获取真实矿池地址
func (c *Config) GetRealPoolAddress() string {
	return c.RealPoolAddress
}

// Validate 验证配置的有效性
func (c *Config) Validate() error {
	if c.ListeningAddress == "" {
		return &ConfigError{Field: "listening_address", Message: "监听地址不能为空"}
	}
	if c.RealPoolAddress == "" {
		return &ConfigError{Field: "real_pool_address", Message: "真实矿池地址不能为空"}
	}
	return nil
}

// ConfigError 配置错误类型
type ConfigError struct {
	Field   string
	Message string
}

func (e *ConfigError) Error() string {
	return e.Field + ": " + e.Message
}

总结

➡️ 定义配置结构体

➡️ 设定默认值 DefaultConfig()

➡️ 加载配置文件

➡️ 支持命令行/环境变量覆盖

➡️ 提供统一访问接口,校验配置有效性等 (如 Config 接口 ,Validate ,ConfigError)