[英]JSON Serialization of external type issue - convert map[string]interface{} item to int
I want to serialize the type Dense
of package gonum.org/v1/gonum/mat
.我想序列化包
gonum.org/v1/gonum/mat
Dense
类型。 Because of the fact, that I cannot implement methods for external types, I created a type因为我无法为外部类型实现方法,所以我创建了一个类型
type DenseEx struct {
Mtx *mat.Dense
}
and implemented MarshalJSON
method as follows并实现
MarshalJSON
方法如下
func (d DenseEx) MarshalJSON() ([]byte, error) {
js := map[string]interface{}{}
rows, cols := d.Mtx.Dims()
js["cols"] = cols
js["rows"] = rows
fltVals := make([]float64, cols*rows)
for r := 0; r < rows; r++ {
for c := 0; c < cols; c++ {
i := r*cols + c
fltVals[i] = d.Mtx.At(r, c)
}
}
js["values"] = fltVals
return json.Marshal(js)
}
This works as expected.这按预期工作。 Now I have issues to unmarshal the structure.
现在我有解组结构的问题。
func (d DenseEx) UnmarshalJSON(data []byte) error {
js := map[string]interface{}{}
err := json.Unmarshal(data, &js)
if err != nil {
return err
}
intf, ok := js["cols"]
if !ok {
return fmt.Errorf("tag 'cols' missing in JSON data")
}
var cols, rows int
cols, ok = intf.(int)
if !ok {
return fmt.Errorf("tag 'cols' cannot be converted to int")
}
...
return nil
}
I am not able to convert the value of the tags to its correct type.我无法将标签的值转换为其正确的类型。 My test json string is
我的测试json字符串是
var jsonStrs = []struct {
str string
expected DenseEx
description string
}{
{
str: "{\"cols\":3,\"rows\":2,\"values\":[6,1,5,2,4,3]}",
expected: DenseEx{
Mtx: nil,
},
description: "deserialization of a 2x3 matrice",
},
}
and my test code is我的测试代码是
...
for _, d := range jsonStrs {
var m DenseEx
err := m.UnmarshalJSON([]byte(d.str))
...
I always get the result我总是得到结果
matex_test.go:26: FAIL: deserialization of a 2x3 matrice: tag 'cols' cannot be converted to int
Any ideas?有任何想法吗?
Thanks in advance!提前致谢!
if you check the docs of Unmarshal.如果您查看 Unmarshal 的文档。 You will find that the know type of Numbers in Unmarshal is
float64
你会发现Unmarshal中Numbers的已知类型是
float64
To unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:要将 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
So, when you try to Unmarshal an int you will get it as float 64. One should type assert it first to float64
intf.(float64)
then convert it to int
因此,当您尝试对 int 进行解组时,您将得到它为 float 64。您应该先将 assert 输入到
float64
intf.(float64)
然后将其转换为int
for example :例如 :
intf, ok := js["cols"]
if !ok {
return fmt.Errorf("tag 'cols' missing in JSON data")
}
var cols, rows int
ucols, ok := intf.(float64)
if !ok {
return fmt.Errorf("tag 'cols' cannot be converted to float64")
}
cols = int(ucols)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.