8

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

 2 years ago
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.
neoserver,ios ssh client

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

原创

峰啊疯了 2022-03-25 11:52:32 ©著作权

文章标签 json 自动生成 赋值 文章分类 Go语言 编程语言 阅读数692

1.导入包

import (
"encoding/json"
"fmt"
)

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

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

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(复杂的对象直接用神器生成对象)_赋值_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(复杂的对象直接用神器生成对象)_赋值_06

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

  • 打赏
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK