setting模块:
type Setting struct {
vp *viper.Viper
}
func NewSetting() (*Setting, error) {
vp := viper.New()
vp.SetConfigName("config")
vp.AddConfigPath("configs/")
vp.SetConfigType("yaml")
err := vp.ReadInConfig()
if err != nil {
return nil, err
}
return &Setting{vp: vp}, nil
}
section模块
type ServerSettingS struct {
RunMode string
HttpPort string
ReadTimeout time.Duration
WriteTimeout time.Duration
}
func (s *Setting) ReadSection(k string, v interface{}) error {
err := s.vp.UnmarshalKey(k, v)
if err != nil {
return err
}
return nil
}
global模块:
var ServerSetting *setting.ServerSettingS
main模块:
setting, err := setting.NewSetting()
setting.ReadSection("Server", &global.ServerSetting)
在main模块中若把第二行改为setting.ReadSection("Server", global.ServerSetting)
,则会报错result must be addressable (a pointer)
请问这是怎么回事
global.ServerSetting不是已经是一个指针了吗,为甚么在ReadSection传参的时候必须取这个指针的地址呢
在 viper 源码中写到了
所以问题的关键是,你传递的参数不仅仅要求是一个指针,并且它可以被寻址,也就是
can be addressable
。所以当你传递的是一个结构体的指针时,它并不能被寻址,所以出错了。
那至于什么可以被寻址,什么不可以被寻址,已经为什么指针不能被寻址,可以参考下面的链接:
go-addressable
GoAddressableValues