Hi everyone, thanks for your time. In the following code of mine, I had a nil pointer exception which I’m not sure why it happened:
package config
type Config struct {
DbStr string `mapstructure:"DB_STRING"`
DbName string `mapstructure:"DB_NAME"`
Port uint32 `mapstructure:"PORT"`
}
var LoadedConfig Config
var isConfigLoaded bool
func loadConfig(path string) (err error) {
viper.SetDefault("PORT", 3000)
viper.AddConfigPath(path)
viper.SetConfigName("app")
viper.SetConfigType("env")
viper.AutomaticEnv()
if err = viper.ReadInConfig(); err != nil {
return
}
err = viper.Unmarshal(&LoadedConfig)
if err == nil {
isConfigLoaded = true
}
return
}
func GetConfig(path string) (config *Config, err error) {
if isConfigLoaded {
return &LoadedConfig, nil
}
err = loadConfig(path)
return
}
In the main.go
file, I just run config, err := config.GetConfig(".")
but then gets a panic: runtime error: invalid memory address or nil pointer dereference
I think the reason is that I tried to marshal the package-level Config variable, which is believed to be a nil(though I think it’s not nil since it’s a zero-valued variable of struct)
Interestingly, when I tried changing the loadedConfig into var configInstance *Config
then it works (of course with modified code).
FYI this is the successful code after modification:
package config
var configInstance *Config
func loadConfig(path string) (err error) {
config := Config{}
viper.SetDefault("PORT", 3000)
viper.AddConfigPath(path)
viper.SetConfigName("app")
viper.SetConfigType("env")
viper.AutomaticEnv()
if err = viper.ReadInConfig(); err != nil {
return
}
err = viper.Unmarshal(&config)
if err == nil {
configInstance = &config
}
return
}
func GetConfig(path string) (*Config, error) {
if configInstance != nil {
return configInstance, nil
}
err := loadConfig(path)
return configInstance, err
}
Could you please help me understand why the zeroed-value struct at package-level can’t be used for marshalling? Thank you!