8
详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)
source link: https://blog.51cto.com/u_12040959/5147475
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
详解golang的json解析方法Marshal跟 Unmarshal(复杂的对象直接用神器生成对象)
原创1.导入包
import (
"encoding/json"
"fmt"
)
"encoding/json"
"fmt"
)
2.对象结构
type Person struct {
Name string
Weight int
}
Name string
Weight int
}
要求:对象的字段名一定是大写字母开头,不然解析会报错,如果字段打上json标签就用标签的key,标签需要小写开头
如Name旁边的 json:"name"
。
循环的对象(比如树,链表等等)不能用json,不然会使,marshal陷入循环
type Person struct {
Name string `json:"name"`
Weight int
}
Name string `json:"name"`
Weight int
}
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)
}
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对象
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
}
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
}
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)
}
// 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
}
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/
推荐这个神器可以自动生成对象,非常的好用
如果这篇文章帮到了你,希望你可以帮小编投投票,47号峰啊疯了,投完可以抽奖哦
- 打赏
- 赞
- 收藏
- 评论
- 分享
- 举报
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK