go-simplejson是go lang语言中操作json非常方便的开源库。最近使用simplejson进行数据插入操作时遇到了问题,经过排查后最终解决。现记录如下。
#
问题描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| // 创建了一个json对象J,需要从其他地方获取剩余json信息后,插入到J中的data字段中。初始版本如下:
import (
"fmt"
simplejson "github.com/bitly/go-simplejson"
)
func main() {
js, _ := simplejson.NewJson([]byte(`
{
"errno": 0,
"errmsg": "test"
}`))
var js_2 = new(simplejson.Json)
*js_2 = *js
jsArr := []*simplejson.Json{}
js1, _ := simplejson.NewJson([]byte(`{"num": 1}`))
js2, _ := simplejson.NewJson([]byte(`{"num": 2}`))
jsArr = append(jsArr, js1)
jsArr = append(jsArr, js2)
js.Set("data", jsArr)
js.Get("data").GetIndex(0).Set("test", 1)
jsB, _ := js.MarshalJSON()
fmt.Println(string(jsB))
}
// % go run js_check.go
// {"data":[{"num":1},{"num":2}],"errmsg":"test","errno":0}
|
#
问题排查
经过dlv
逐行调试,实际问题出在js.Get("data").GetIndex(0).Set("test", 1)
中。跳转至定义,该操作实际做如下转换:
1
2
3
4
| arr, ok := js.Get("data").data.([]interface{})
if ok {
&simplejson.Json(arr[index]).Set("test", 1)
}
|
这里由于jsArr
是[]*simplejson.Json
,类型断言为[]interface{}
失败。所以无法正常设置值。查看simplejson.go
,其中的Json
对象结构如下:
1
2
3
| type Json struct {
data interface{}
}
|
其实可以通过js.Interface()
获取其中的真实数据。
#
解决方案
变更为如下代码即可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| package main
import (
"fmt"
simplejson "github.com/bitly/go-simplejson"
)
func main() {
js, _ := simplejson.NewJson([]byte(`
{
"errno": 0,
"errmsg": "test"
}`))
var js_2 = new(simplejson.Json)
*js_2 = *js
jsArr := []interface{}{}
js1, _ := simplejson.NewJson([]byte(`{"num": 1}`))
js2, _ := simplejson.NewJson([]byte(`{"num": 2}`))
jsArr = append(jsArr, js1.Interface())
jsArr = append(jsArr, js2.Interface())
js.Set("data", jsArr)
js.Get("data").GetIndex(0).Set("test", 1)
jsB, _ := js.MarshalJSON()
fmt.Println(string(jsB))
}
// % go run js_check.go
// {"data":[{"num":1,"test":1},{"num":2}],"errmsg":"test","errno":0}
|