json - 在 Interface{} 中存储配置结构并将其转换回原始结构
问题描述
我尝试做什么
我为 s 编写了一个模板App
每个App
都有一个配置 - 因此我想将 s 存储Config
到App
struct
.
我所有的config
s 都存储在其中JSON
- 因此我想提供一个通用func
的加载JSON
const JSON = `{
"Name": "TestConfig"
}`
注意:我尝试使用和不使用指针来解决我的问题,两者都会导致相同的错误消息 - 两个版本都包含在下面。
因此,让我们将 App-Template 视为:
type App struct {
config interface{}
configPtr *interface{}
}
和一个Configuration
:
// ConfigurationA is an actual implementation of the Config (Application A)
type ConfigurationA struct {
Name string
// ... add more properties here
}
此外,我实现了一个func
加载Config
fromfile
并将其存储在App
func (a *App) GeneralConfigLoader(jsonData string, v interface{}) (err error) {
// load json -> struct
err = json.Unmarshal([]byte(jsonData), &v)
if err != nil {
fmt.Println("error unmarshalling JSON data")
return err
}
a.config = v
a.configPtr = &v
return nil
}
由于我有一个具有一般负载的应用程序,func
因此现在应该可以创建一个简单func
的将空接口转换为正确的配置结构。
// Config - Config of the App
func Config(a *App) *ConfigurationA {
var cfg ConfigurationA = a.config.(ConfigurationA)
return &cfg
}
// ConfigPtr - Config of the App
func ConfigPtr(a *App) *ConfigurationA {
var i interface{} = *a.configPtr
return i.(*ConfigurationA)
}
如果我将其总结为可执行文件,例如:
func main() {
var conf ConfigurationA // the interface used as Configuration
var a = &App{}
a.GeneralConfigLoader(JSON, conf)
//panics: interface conversion: interface {} is map[string]interface {}, not main.ConfigurationA
var cfg = Config(a)
fmt.Println("cfg -> ", cfg)
//panics: interface conversion: interface {} is map[string]interface {}, not *main.ConfigurationA
var cfgPtr = ConfigPtr(a)
fmt.Println("cfgPtr -> ", cfgPtr)
}
应用程序恐慌(上一节中的评论......)
为什么 go 会省略类型信息?
或者更好...为什么我不能将配置转换回原来的样子,因为我知道它是什么...?
注意
如果我不使用这个通用加载器并创建它确实有效的具体实现!
问题:
我究竟做错了什么?
使用 go 是不可能的(怀疑)?
解决方案
将指针传递给 GeneralConfigLoader。解组该指针。删除字段App.configPtr
。它没有用,也不符合您的期望。
func (a *App) GeneralConfigLoader(jsonData string, v interface{}) (err error) {
err = json.Unmarshal([]byte(jsonData), v) // & removed here
if err != nil {
fmt.Println("error unmarshalling JSON data")
return err
}
a.config = v
return nil
}
func Config(a *App) *ConfigurationA {
return a.config.(*ConfigurationA)
}
像这样加载配置:
var config ConfigurationA
var a = &App{}
a.GeneralConfigLoader(JSON, &config) // & added here
推荐阅读
- javascript - 来自 Ajax 调用的 JSON 数据
- python - 从字典选择中填充 pyqt5 输入
- arrays - 对角数组求和
- kubernetes - 无法使用 AWS Elastic LoadBalancer 创建 Kubernetes 服务
- ios - 以编程方式设置包括不安全区域的背景图像(Swift)
- r - 使用 [Is Na] 解决供应来源错误
- api - 带有 Django Rest 框架的 API 结构
- gradle - 使用 fmpp 排除处理文件夹(但复制它)
- react-native - 试图注册两个同名的视图 RNGestureHandlerButton
- python - Windows:ModuleNotFoundError:没有名为“distutils”的模块