尝试使用Unmarshal
将hcl
配置文件viper
到结构中,返回此错误:1 error(s) decoding:\n\n* 'NATS' expected a map, got 'slice'
。什么不见了?
代码:
func lab() {
var c conf
// config file
viper.SetConfigName("draft")
viper.AddConfigPath(".")
viper.SetConfigType("hcl")
if err := viper.ReadInConfig(); err != nil {
log.Error(err)
return
}
log.Info(viper.Get("NATS")) // gives [map[port:10041 username:cl1 password:__Psw__4433__ http_port:10044]]
if err := viper.Unmarshal(&c); err != nil {
log.Error(err)
return
}
log.Infow("got conf", "conf", c)
}
type conf struct {
NATS struct {
HTTPPort int
Port int
Username string
Password string
}
}
和配置文件(当前目录内的
draft.hcl
):NATS {
HTTPPort = 10044
Port = 10041
Username = "cl1"
Password = "__Psw__4433__"
}
编辑
已经使用
hcl
包检查了此结构,并且正确地将其编码/解码。这也可以与yaml
和viper
一起正常工作。调用
log.Info(viper.Get("NATS"))
的这两者之间是有区别的。虽然hcl
版本返回 map slice ,但yaml
版本返回 map :map[password:__psw__4433__ httpport:10044 port:10041 username:cl1]
。 最佳答案
您的结构与HCL不匹配。转换为json时,HCL如下所示
{
"NATS": [
{
"HTTPPort": 10044,
"Password": "__Psw__4433__",
"Port": 10041,
"Username": "cl1"
}
]
}
因此
Conf
结构应该看起来像这样type Conf struct {
NATS []struct{
HTTPPort int
Port int
Username string
Password string
}
}
修改后的代码
package main
import (
"log"
"github.com/spf13/viper"
"fmt"
)
type Conf struct {
NATS []struct{
HTTPPort int
Port int
Username string
Password string
}
}
func main() {
var c Conf
// config file
viper.SetConfigName("draft")
viper.AddConfigPath(".")
viper.SetConfigType("hcl")
if err := viper.ReadInConfig(); err != nil {
log.Fatal(err)
}
fmt.Println(viper.Get("NATS")) // gives [map[port:10041 username:cl1 password:__Psw__4433__ http_port:10044]]
if err := viper.Unmarshal(&c); err != nil {
log.Fatal(err)
}
fmt.Println(c.NATS[0].Username)
}