问题背景
通过viper解析文件内容映射config一直失败,相关代码如下
type Config struct {DBConf *DBConf `toml:"db"`RedisConf *RedisConf `toml:"redis"`WebConfig *WebConfig `toml:"app"`
}type DBConf struct {Read struct {Dsn string `toml:"dsn"` // 最高优先级} `toml:"read"`Write struct {Dsn string `toml:"dsn"` // 最高优先级} `toml:"write"`Base struct {Type string `toml:"type"`MaxOpenConn int `toml:"maxOpenConn"`MaxIdleConn int `toml:"maxIdleConn"`ConnMaxLifeTime time.Duration `toml:"connMaxLifeTime"`} `toml:"base"`
}type CacheType stringtype RedisConf struct {Address string `toml:"addr"`DB string `toml:"db"`Password string `toml:"password"`
}type WebConfig struct {Port string `toml:"port"`IsDebug bool `toml:"debug"`LogFilePath string `toml:"path"`
}appFullPath := "./conf/" + filePath// 解析 configviper.SetConfigName("web")viper.AddConfigPath(appFullPath)viper.SetConfigType("yaml")err := viper.ReadInConfig()if err != nil {log.Fatal("解析文件失败: ", err)}if err := viper.Unmarshal(&conf); err != nil {log.Fatal("解析文件失败: ", err)}// 监听配置更新viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {if err := viper.Unmarshal(&conf); err != nil {log.Fatal("解析文件失败: ", err)}})
问题原因
Viper使用的是 github.com/mitchellh/mapstructure来解析值
mapstructure 用于将通用的map[string]interface{}解码到对应的 Go 结构体中
默认情况下,mapstructure 使用结构体中字段的名称做这个映射,不区分大小写,比如 Name 字段可以映射到
name、NAME、NaMe 等等,如果名称不一致没有指定 tagName ,则默认为 mapstructure,这也是为什么带下划线或者名称不一致的字段不加 mapstructure标签无法解析的原因
解决方案
mapstructure方法
通过mapstructure映射名称