为了账号安全,请及时绑定邮箱和手机立即绑定

外部类型问题的 JSON 序列化 - 将 map[string]interface{} 项转换为

外部类型问题的 JSON 序列化 - 将 map[string]interface{} 项转换为

Go
拉丁的传说 2022-05-23 17:12:24
我想序列化Dense包的类型gonum.org/v1/gonum/mat。因为我无法实现外部类型的方法,所以我创建了一个类型type DenseEx struct {    Mtx *mat.Dense}并实现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)}这按预期工作。现在我有解组结构的问题。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}我无法将标签的值转换为正确的类型。我的测试 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",    },}我的测试代码是...for _, d := range jsonStrs {    var m DenseEx    err := m.UnmarshalJSON([]byte(d.str))...我总是得到结果matex_test.go:26: FAIL: deserialization of a 2x3 matrice: tag 'cols' cannot be converted to int有任何想法吗?提前致谢!
查看完整描述

1 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

如果您查看 Unmarshal 的文档。你会发现 Unmarshal 中已知的 Numbers 类型是float64


为了将 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

因此,当您尝试 Unmarshal an int 您将得到它作为 float 64。应该先键入 assert 它float64 intf.(float64)然后将其转换为int


例如 :


    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)


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 313 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号