Viper 极简配置读取指南
Viper 是 Go 语言中一个非常方便的配置库。如果你想从文件中读取配置,并将其映射到 Go 结构体以便于类型安全的调用,Viper 能轻松搞定。
1. 安装 Viper
首先,确保你的项目安装了 Viper
1
| go get github.com/spf13/viper
|
2. 准备配置文件
Viper 支持多种配置文件格式,比如 YAML、JSON、TOML 等。我们以 YAML 格式为例,创建一个名为 config.yaml 的文件在你的项目根目录下:
1 2 3 4 5 6 7 8 9 10
| server: port: 8080 name: MyWebApp database: host: localhost user: admin password: supersecret timeout_seconds: 10
|
3. 编写 Go 代码读取配置并绑定到结构体
下面是一个简单的 Go 程序,演示了如何使用 Viper 读取 config.yaml 文件中的配置,并将其绑定到一个 Go 结构体。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| package main
import ( "fmt" "log"
"github.com/spf13/viper" )
type Config struct { Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"` }
type ServerConfig struct { Port int `mapstructure:"port"` Name string `mapstructure:"name"` }
type DatabaseConfig struct { Host string `mapstructure:"host"` User string `mapstructure:"user"` Password string `mapstructure:"password"` TimeoutSeconds int `mapstructure:"timeout_seconds"` }
func main() { viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".") viper.AddConfigPath("./config")
if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { fmt.Println("No config file found, continuing with defaults or environment variables.") } else { log.Fatalf("Fatal error reading config file: %s \n", err) } } else { fmt.Printf("Config file '%s' loaded successfully!\n", viper.ConfigFileUsed()) }
var appConfig Config
appConfig.Database.TimeoutSeconds = 10
if err := viper.Unmarshal(&appConfig); err != nil { log.Fatalf("Unable to unmarshal config into struct: %s \n", err) }
fmt.Println("\n--- 通过结构体访问配置 ---") fmt.Printf("Server Name: %s\n", appConfig.Server.Name) fmt.Printf("Server Port: %d\n", appConfig.Server.Port) fmt.Printf("Database Host: %s\n", appConfig.Database.Host) fmt.Printf("Database User: %s\n", appConfig.Database.User) fmt.Printf("Database Password: %s\n", appConfig.Database.Password) fmt.Printf("Database Timeout (seconds): %d\n", appConfig.Database.TimeoutSeconds)
fmt.Println("\n--- 直接通过 Viper.Get() 访问配置 ---") fmt.Printf("Server Port (from Viper.GetInt): %d\n", viper.GetInt("server.port")) }
|
4. 运行你的程序
将上面的 Go 代码保存为 main.go。
确保 config.yaml 文件与 main.go 在同一目录下。
打开终端,进入该目录,然后运行:
你将看到程序成功读取 config.yaml,并将其内容绑定到 appConfig 结构体,然后通过结构体字段访问配置值。
结构体绑定小贴士:
mapstructure 标签: mapstructure:"key_name" 告诉 Viper 如何将配置文件中的 key_name 字段映射到 Go 结构体的对应字段。这是必不可少的。
- 嵌套结构体: 对于配置文件中的嵌套配置(如
server 和 database),Go 结构体也应使用嵌套结构体来匹配。
- 默认值: 如果结构体字段是基本类型(如
int, string, bool),并且你在代码中给它赋了初始值(例如 TimeoutSeconds int = 10),那么在配置文件中没有这个键时,这个默认值就会被保留。如果配置文件有,则会被覆盖。