[英]How to unmarshal a slice of interfaces from JSON in Golang
我有一个variables
包,其中有一个接口Variable
和两个实现接口上的方法的结构NumericalVariable
和TextualVariable
,就像这样......
package variables
type Variable interface {
GetColumnIndex() int
IsActive() bool
StartDataLoad()
AddData(value string) (bool, error)
FinishDataLoad()
VectorLength() int
SetVectorOffset(offset int)
LoadIntoVector(sv string, vector []float64) float64
}
type NumericVariable struct {
Column_idx int
Name string
Vector_offset int
Mean float64
Sum float64
SumSq float64
SD float64
Count float64
Max float64
Min float64
Vector_max float64
Vector_min float64
values []float64
Active bool
}
type Category struct {
Count int
Vector_offset int
Coefficient float64
}
type TextualVariable struct {
Column_idx int
Name string
Vector_offset int
Categories map[string]Category
Categories_k float64
Active bool
Count int
}
我有另一个模块model
,它定义了一个Model
类型,其中包括一个Variable
接口,像这样......
package model
type Model struct {
Vars []variables.Variable
}
在我在其他地方的代码中,我正在加载和处理数据流/文件,并根据呈现的数据创建NumericalVariable
或TextualVariable
实例。 这些被添加到Model
实例的Vars
切片中
我希望能够读取Model
结构并将其写入 JSON 文件。
写作很容易,我利用了 Golang 的json
包中的编组(只要我对大写的变量名感到满意)
func (_self Model) Write(filename string) {
file, err := json.MarshalIndent(_self, "", " ")
if err != nil {
log.Fatal(err)
return
}
err = ioutil.WriteFile(filename, file, 0644)
if err != nil {
log.Fatal(err)
return
}
}
然而,从 JSON 中读取被证明更棘手。 问题在于model.Vars
是接口的一部分。 封送处理程序处理得很好,但是当我回读时,我没有关于所写类型的信息。
我以为我可以通过反思来解决这个问题,我快到了,但我被困住了。
我的读者长这样...
func (_self Model) Read(filename string) {
_model, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
return
}
var dat map[string][]interface{}
err = json.Unmarshal([]byte(_model), &dat)
if err != nil {
log.Fatal(err)
return
}
_vars := dat["Vars"]
for _, _vi := range _vars {
k := reflect.ValueOf(_vi)
if k.Kind() == reflect.Map {
if len(k.MapKeys()) == 13 {
// I know this is a numeric variable
nv := variables.NumericVariable()
// How do I get the reflect kind to load up nv
}
if len(k.MapKeys()) == 8 {
// I know this is a textual variable
tv := variables.TextualVariable()
// How do I get the reflect kind to load up tv
}
}
}
我可以可靠地(如果有点笨拙)检测到反射中何时具有每种类型,但是如何让它将值加载到结构中。 理想情况下,我希望自动解组到同名的结构变量中。 我不想一个接一个地做(虽然我可能不得不求助于那个),但我该怎么做呢?
通过将类型断言为地图的值,直接将您的地图[字符串]接口{}转换为结构
var nv NumericVariable
for key,value:= range vars {
nv.Column_idx = vars[key].(int) // interface{} will be converted to int
nv.Name = vars[key].(string) // interface{} will be converted to string
..
..
}
将 map 的接口值转换为 struct 中给定类型的断言类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.