go - 使用 viper 从 envfile 读取配置
问题描述
我真的不明白毒蛇是如何工作的。这是我的代码:
配置.go
var Config *Configuration
type ServerConfiguration struct {
Port string
}
type Configuration struct {
Server ServerConfiguration
}
func Init() {
var configuration *Configuration
viper.SetConfigFile(".env")
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
err := viper.Unmarshal(&configuration)
if err != nil {
log.Fatalf("Unable to decode into struct, %v", err)
}
Config = configuration
}
func GetConfig() *Configuration {
return Config
}
.env
SERVER_PORT=:4747
问题是 Unmarshal 不起作用当我使用例如 configuration.Server.Port 它是空的
解决方案
spf13/viper主要使用mapstructure包在一种本机 Go 类型之间转换为另一种,即在取消编组时。该包在内部使用map[string]interface{}
type 来存储您的配置(请参阅viper.go - L1327)。之后,根据配置类型(您的情况是env
),viper 调用正确的解析包来存储您的配置值。对于 envfile 类型,它使用subposito/gotenv放入上述映射类型(参见viper.go - L1501)
您的问题的症结在于如何使 viper 在映射中将此配置解组为您选择的结构。这是 mapstructure 包进来的地方,将地图解组为您定义的嵌套结构。此时,您有两个选择
- 将配置解组为
map[string]interface{}
类型,然后使用 mapstructure 放入适当的结构 - 使用DecodeHookFunc作为方法的第二个参数来解组您的配置(参见viper.go - L904)
为了简单起见,您可以做一个,根据我用您的示例复制的一个简单示例,可以在下面完成
package main
import (
"fmt"
"github.com/mitchellh/mapstructure"
"github.com/spf13/viper"
)
type ServerConfiguration struct {
Port string `mapstructure:"server_port"`
}
type Configuration struct {
Server ServerConfiguration `mapstructure:",squash"`
}
func main() {
var result map[string]interface{}
var config Configuration
viper.SetConfigFile(".env")
if err := viper.ReadInConfig(); err != nil {
fmt.Printf("Error reading config file, %s", err)
}
err := viper.Unmarshal(&result)
if err != nil {
fmt.Printf("Unable to decode into map, %v", err)
}
decErr := mapstructure.Decode(result, &config)
if decErr != nil {
fmt.Println("error decoding")
}
fmt.Printf("config:%+v\n", config)
}
您可以根据您的实际用例定制此工作示例。squash
有关嵌入式结构的 mapstructure 标签的更多信息,请参见此处
推荐阅读
- rx-java - 关于Maybe的反应性(rxjava)问题
- 与流动等
- r - L-BFGS-B 需要 'fn' 的有限值
- java - 复合主键表未填充到相关实体中
- c# - 如何在不使用服务模型的情况下反序列化 json 列表?
- java - Maven - 为java项目中的每个java包创建一个jar
- android - 将表盘部署到设备
- jquery - 如何使用 .selectmenu jquery ui 自动填充信用卡数据?
- javascript - 升级到 3.1 版本后 NokiaHere 地图渲染问题
- windows - 不同 Windows 版本的默认执行策略是什么?
- laravel - 我如何将 Laravel 的 Bootstrap 4 降级到 3.3.7