我正在尝试编写一个采用json文件名和配置结构的配置包。它应该将json解组到传入的结构中并返回它。 我正在尝试使用界面,以便可以传递我想要的任何结构
错误是:
panic: interface conversion: interface {} is map[string]interface {}, not *main.ConfigurationData
我不太确定如何解决此问题。
这是我的主要包裹
package main
import (
"config"
"commons"
)
type ConfigurationData struct {
S3ARN string `json:"S3ARN"`
SQSQueueUrl string `json:"SQSQueueUrl"`
}
var configData *ConfigurationData
func main(){
configData=config.Load("aws.config.json",configData).(*ConfigurationData)
commons.Dump(configData)
}
这是我的配置包
package config
import (
"os"
"encoding/json"
"sync"
"commons"
)
var configLock = new(sync.RWMutex)
func Load(filename string,config interface{})interface{} {
file, err := os.Open(filename)
commons.CheckErrorf(err, "Config Open Error")
defer file.Close()
decoder := json.NewDecoder(file)
configLock.Lock()
err = decoder.Decode(&config)
commons.CheckErrorf(err, "Config Decode Error")
configLock.Unlock()
return config
}
答案 0 :(得分:1)
此answer很好地解释了为什么您会收到异常。
您应该做什么:
当 encoding / json 包遇到实现 Marshaler 接口的类型时,它将使用该类型的MarshalJSON()
方法而不是默认的封送处理代码来将对象转换为JSON。同样,在解码JSON对象时,它会测试该对象是否实现了 Unmarshaler 接口,如果是,它将使用UnmarshalJSON()
方法而不是默认的非编组行为。
为此,我的解决方案是在*ConfigurationData
上实现 UnmarshalJSON 方法,并且方法Load
应该接受Unmarshaler接口,而不是interface{}
。 / p>
您可以在此处了解有关技术的更多信息:https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
然后,您可以简单地在json.Unmarshal(b, &config)
方法中执行Load
,其中 b 是从文件中[]byte
读取的。
答案 1 :(得分:0)
根据documentation on json.Unmarshall解组为接口值将解组为预定义类型之一的新结构:
要将JSON解组为接口值,Unmarshal存储以下内容之一: 这些在界面值中:
bool, for JSON booleans float64, for JSON numbers string, for JSON strings []interface{}, for JSON arrays map[string]interface{}, for JSON objects nil for JSON null
在您的情况下,选择的类型为map[string]interface{}
。在您的函数中,指向该新未编组结构的指针存储在config参数中并返回。之所以会出现恐慌,是因为返回的值的类型不是您所断言的类型。