猿问

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

我想序列化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

有任何想法吗?


提前致谢!


拉丁的传说
浏览 314回答 1
1回答

神不在的星期二

如果您查看 Unmarshal 的文档。你会发现 Unmarshal 中已知的 Numbers 类型是float64为了将 JSON 解组为接口值,Unmarshal 将其中一项存储在接口值中:bool, for JSON booleansfloat64, for JSON numbersstring, for JSON strings[]interface{}, for JSON arraysmap[string]interface{}, for JSON objectsnil for JSON null因此,当您尝试 Unmarshal an int 您将得到它作为 float 64。应该先键入 assert 它float64 intf.(float64)然后将其转换为int例如 :&nbsp; &nbsp; intf, ok := js["cols"]&nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("tag 'cols' missing in JSON data")&nbsp; &nbsp; }&nbsp; &nbsp; var cols, rows int&nbsp; &nbsp; ucols, ok := intf.(float64)&nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("tag 'cols' cannot be converted to float64")&nbsp; &nbsp; }&nbsp;&nbsp; &nbsp; cols = int(ucols)
随时随地看视频慕课网APP

相关分类

Go
我要回答