json的本质就是数组和字典的组合,但系统的数组和字典都是确定类型的,所以,go的interface{}就能大显身手了。
下面的代码描述了自定义类型 List
和Dict
。有了这两个工具,处理json就非常的方便。
package main
import (
"encoding/json"
"fmt"
)
type List []interface{}
func ToList(obj interface{}) List {
switch obj := obj.(type) {
case []interface{}:
return obj
case string:
var f interface{}
err := json.Unmarshal([]byte(obj), &f)
if err != nil {
panic("ToList err" + err.Error())
}
return f.([]interface{})
}
panic("ToList failed, input type not in ([]interface{}, string)")
}
func (l *List) String() string {
result, err := json.Marshal(l)
if err != nil {
panic("json to string error" + err.Error())
}
return string(result)
}
type Dict map[string]interface{}
func ToDict(obj interface{}) Dict {
switch obj := obj.(type) {
case map[string]interface{}:
return obj
case string:
var f interface{}
err := json.Unmarshal([]byte(obj), &f)
if err != nil {
panic("ToDict err" + err.Error())
}
return f.(map[string]interface{})
}
panic("ToDict failed, input type not in (map[string]interface{}, string)")
}
func (d *Dict) String() string {
result, err := json.Marshal(d)
if err != nil {
panic("json to string error" + err.Error())
}
return string(result)
}
func main() {
// test Dict
objmap := make(map[string]interface{})
objmap["name"] = "yzh"
objmap["age"] = 28
objdict := ToDict(objmap)
fmt.Println(objdict.String())
objdict["age"] = 18
fmt.Println(objdict.String())
dictstr := `{"age":28,"name":"yzh"}`
objdict = ToDict(dictstr)
objdict["age"] = 16
fmt.Println(objdict.String())
// test List
objarray := make([]interface{}, 0)
objarray = append(objarray, "haha")
objlist := ToList(objarray)
objlist = append(objlist, objdict)
objlist[0] = "haha2"
fmt.Println(objlist.String())
objlist = ToList(`["haha2",{"age":16,"name":"yzh"}]`)
objlist[0] = "haha3"
fmt.Println(objlist.String())
}
简简单单写了一个函数,用来处理json。终于不用定义一大堆结构体了。
/*
myJson是对json的封装,用interface{} 屏蔽了对结构体的使用依赖。常见操作如下:
type TestStruct struct {
ID int
Name string
}
func TestJson() {
jsonStr := []byte("{\"hi\":\"hello\",\"myarr\":[{\"my\":\"zhh\"}]}")
jsonObj := myJson.NewFromBytes(jsonStr)
appendStr := []byte("{\"you\":\"dazhu\"}")
appendObj := myJson.NewFromBytes(appendStr)
logger.Info("%s", jsonStr)
// 获取相应值,并设置值
if jsonObj.Get("hi").String() != "null" {
jsonObj.Set("hi", "haha")
}
// 获取一个slice中的对应值,并设置它
jsonObj.Get("myarr").Index(0).Set("my", "zhhdazhu")
// 在slice中添加新的元素
jsonObj.AppendKey("myarr", appendObj)
// 判定一个值是否存在
if jsonObj.Get("haha123").String() == "null" {
logger.Info("haha123 not exist")
}
// 将myjson对象转为json字符串
testObj := jsonObj.String()
logger.Info(testObj)
// 从结构体创建myJson对象
stcObj := TestStruct{ID: 1, Name: "yzh"}
jsonObj2 := myJson.NewFromStruct(stcObj)
logger.Info("%s", jsonObj2.String())
}
*/
package common
import (
"encoding/json"
"fmt"
)
type MyJson struct {
prev *MyJson
prevkey string
previndex int
data interface{}
}
// NewJson 从其它对象创建myJson对象。
func NewJson(data interface{}) *MyJson {
switch v := data.(type) {
case string:
return NewJsonFromStr(v)
case []byte:
return NewJsonFromBytes(v)
default:
return NewJsonFromData(v)
}
}
// NewJsonFromBytes 从bytes对象创建myJson对象。bytes对象必须是标准的json格式。
func NewJsonFromBytes(b []byte) *MyJson {
var f interface{}
err := json.Unmarshal(b, &f)
if err != nil {
panic("NewMyJson err" + err.Error())
}
return &MyJson{data: f}
}
// NewJsonFromStr 从一个字符串对象创建myJson对象
func NewJsonFromStr(str string) *MyJson {
var f interface{}
err := json.Unmarshal([]byte(str), &f)
if err != nil {
errstr := fmt.Sprintf("js解析失败:%v", str)
return NewErrJson(1, errstr)
}
return &MyJson{data: f}
}
func NewErrJson(errcode int, errmsg string) *MyJson {
result := NewJsonFromStr("{}")
result.Set("err_msg", errmsg)
result.Set("err", errcode)
return result
}
// NewJsonFromStruct 从一个结构体对象创建myJson对象
func NewJsonFromStruct(b interface{}) *MyJson {
var f interface{}
bytesArr, err := json.Marshal(b)
if err != nil {
panic("NewMyJson Marshal err" + err.Error())
}
err = json.Unmarshal(bytesArr, &f)
if err != nil {
panic("NewMyJson Unmarshal err" + err.Error())
}
return &MyJson{data: f}
}
func NewJsonFromData(d interface{}) *MyJson {
return &MyJson{data: d}
}
// Get 获取一个key值。
func (j *MyJson) Get(key string) *MyJson {
m, ok := j.data.(map[string]interface{})
if !ok {
return &MyJson{
prev: j,
prevkey: key,
data: nil,
}
}
v := m[key]
return &MyJson{
prev: j,
prevkey: key,
data: v,
}
}
func maintRelation(child *MyJson) {
if child.prev == nil {
return
}
switch child.prev.Value().(type) {
case map[string]interface{}:
child.prev.Set(child.prevkey, child)
case []interface{}:
child.prev.Set(child.previndex, child)
}
}
// Append 往数组中添加值
func (j *MyJson) Append(val interface{}) *MyJson {
if value, ok := val.(*MyJson); ok {
j.data = append(j.data.([]interface{}), value.Value())
} else {
j.data = append(j.data.([]interface{}), val)
}
maintRelation(j)
return j
}
// Insert 往数组中添加值
func (j *MyJson) Insert(index int, val interface{}) *MyJson {
v := j.data.([]interface{})
if value, ok := val.(*MyJson); ok {
rear := append([]interface{}{}, v[index:]...)
v := append(v[0:index], value.Value())
j.data = append(v, rear...)
} else {
rear := append([]interface{}{}, v[index:]...)
v := append(v[0:index], val)
j.data = append(v, rear...)
}
maintRelation(j)
return j
}
// IsNil 判定data最不是空
func (j *MyJson) IsNil() bool {
if j.data == nil {
return true
}
return false
}
// Index 传入位置获取slice对应位置的myjson对象
func (j *MyJson) Index(key int) *MyJson {
m := j.data.([]interface{})
v := m[key]
return &MyJson{prev: j,
previndex: key,
data: v}
}
// AppendKey 添加另一个对象到slice的myjson对象中
func (j *MyJson) AppendKey(key interface{}, val interface{}) *MyJson {
switch v := key.(type) {
case string:
m := j.data.(map[string]interface{})
data := m[v]
if value, ok := val.(*MyJson); ok {
m[v] = append(data.([]interface{}), value.Value())
} else {
m[v] = append(data.([]interface{}), val)
}
case int:
m := j.data.([]interface{})
data := m[v]
if value, ok := val.(*MyJson); ok {
m[v] = append(data.([]interface{}), value.Value())
} else {
m[v] = append(data.([]interface{}), val)
}
}
return j
}
// InsertKey 添加另一个对象到slice的myjson对象中
func (j *MyJson) InsertKey(key string, index int, val interface{}) *MyJson {
m := j.data.(map[string]interface{})
v := m[key].([]interface{})
if value, ok := val.(*MyJson); ok {
rear := append([]interface{}{}, v[index:]...)
v := append(v[0:index], value.Value())
v = append(v, rear...)
m[key] = v
} else {
rear := append([]interface{}{}, v[index:]...)
v := append(v[0:index], value)
v = append(v, rear...)
m[key] = v
}
return j
}
// Set 对当前的myjson对象对应key设置值
func (j *MyJson) Set(key interface{}, val interface{}) *MyJson {
switch v := key.(type) {
case string:
m := j.data.(map[string]interface{})
if value, ok := val.(*MyJson); ok {
m[v] = value.Value()
} else {
m[v] = val
}
case int:
m := j.data.([]interface{})
if value, ok := val.(*MyJson); ok {
m[v] = value.Value()
} else {
m[v] = val
}
}
return j
}
// Value 返回myjson对象的真实数据
func (j MyJson) Value() interface{} {
v := j.data
return v
}
// Len 返回数组对象的长度
func (j MyJson) Len() int {
v := j.data
return len(v.([]interface{}))
}
// String方法返回myjson对象的字符串值
func (j MyJson) String() string {
switch v := j.data.(type) {
case *MyJson:
result, err := json.Marshal(v.data)
if err != nil {
panic("json to string error" + err.Error())
}
return string(result)
default:
return ToStr(j.data)
}
}
// Int 返回myjson对象的真实数据
func (j MyJson) Int() int {
v := j.data
return ToInt(v)
}
// Bool 返回myjson对象的真实数据
func (j MyJson) Bool() bool {
v, ok := j.data.(bool)
if ok {
return v
}
return false
}
// Array 返回数组对象的真实数据
func (j MyJson) Array() []interface{} {
v := j.data
return v.([]interface{})
}