0
点赞
收藏
分享

微信扫一扫

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)

1.导入包

import (
"encoding/json"
"fmt"
)

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_json


2.对象结构

type Person struct {
Name string
Weight int
}

要求:对象的字段名一定是大写字母开头,不然解析会报错,如果字段打上json标签就用标签的key,标签需要小写开头

如Name旁边的 ​​json:"name"​​。

循环的对象(比如树,链表等等)不能用json,不然会使,marshal陷入循环

type Person struct {
Name string `json:"name"`
Weight int
}

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_自动生成_02

3.测试

func main() {
person := &Person{
Name: "hdf",
Weight: 145,
}
b,_ := json.Marshal(person)

var p Person
json.Unmarshal(b,&p)
fmt.Println(p)
os.Stdout.Write(b)
}

b是字节对象,p是person对象

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_json_03

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_json_04

4.源码解读

func Marshal(v interface{}) ([]byte, error) {
e := newEncodeState()

err := e.marshal(v, encOpts{escapeHTML: true})
if err != nil {
return nil, err
}
buf := append([]byte(nil), e.Bytes()...)

encodeStatePool.Put(e)

return buf, nil
}
func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) {
defer func() {
if r := recover(); r != nil {
if je, ok := r.(jsonError); ok {
err = je.error
} else {
panic(r)
}
}
}()
e.reflectValue(reflect.ValueOf(v), opts)
return nil
}

很明显用到了反射,

func Unmarshal(data []byte, v interface{}) error {
// Check for well-formedness.
// Avoids filling out half a data structure
// before discovering a JSON syntax error.
var d decodeState
err := checkValid(data, &d.scan)
if err != nil {
return err
}

d.init(data)
return d.unmarshal(v)
}
func (d *decodeState) unmarshal(v interface{}) error {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr || rv.IsNil() {
return &InvalidUnmarshalError{reflect.TypeOf(v)}
}

d.scan.reset()
d.scanWhile(scanSkipSpace)
// We decode rv not rv.Elem because the Unmarshaler interface
// test must be applied at the top level of the value.
err := d.value(rv)
if err != nil {
return d.addErrorContext(err)
}
return d.savedError
}

Unmarshal传递的是个指针。​否则解析虽不报错,但数据无法赋值到接受体中。

5.复杂的结构体如何解析到对象

​​https://mholt.github.io/json-to-go/​​

推荐这个神器可以自动生成对象,非常的好用

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_自动生成_05

如果这篇文章帮到了你,希望你可以帮小编投投票,47号峰啊疯了,投完可以抽奖哦

​​https://blog.51cto.com/blog-contest/index#part4​​

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_json_06

详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)_自动生成_07


举报

相关推荐

0 条评论