golang-json构建和解析:Marshal与Unmarsha、json转换为map

Go的json解析:Marshal与Unmarshal

Go的json解析:Marshal与Unmarshal
原文链接:https://blog.csdn.net/zxy_666/article/details/80173288

Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输。任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如string类型,strcut对象等。

go语言本身为我们提供了json的工具包”encoding/json”。

Json Unmarshal:将json字符串解码到相应的数据结构。

json.Unmarshal解析匹配规则顺序

json字符串解析时,需要一个“接收体”接受解析后的数据,且Unmarshal时接收体必须传递指针。否则解析虽不报错,但数据无法赋值到接受体中。

解析时,接收体可自行定义。json串中的key自动在接收体中寻找匹配的项进行赋值。匹配规则是:

  1. 先查找与key一样的json标签,找到则赋值给该标签对应的变量(如Name)。
  2. 没有json标签的,就从上往下依次查找变量名与key一样的变量,变量名忽略大小写后与key一样的变量。
    第一个匹配的就赋值,后面就算有匹配的也忽略。
    (前提是该变量必需是可导出的,即首字母大写)。
  3. 当接收体中存在json串中匹配不了的项时,解析会自动忽略该项,该项仍保留原值。

代码demo

demo: 基本使用

导入:"github.com/vmihailenco/msgpack“
调用msgpack.Marshal进行序列化
调用msgpack.Unmarshal进行反序列化

type Person struct{
    
    
    Name string
    Age int
    Sex string
}
func writeJson(filename string)(err error){
    
    
    var persons []*Person
    for i := 0 ; i < 10; i++ {
    
    
        p := &Person{
    
    
                Name:fmt.Sprintf("name%d",i).
                Age:rand.Intn(100),
                Sex:"Man",
            }
        person = append(person,p)
    }
    data,err := msgpack.Marshal(persons)
    if err != nil {
    
    
        fmt.Printf("=marshal failed err:%v \n",err)
        return
    }
    err = ioutil.WriteFile(filename,data,0755)
    if err != nil{
    
    
        fmt.Printf("Write file failed,err:%v \n",err)
        return
    }
}
 
func readJson(filename string)(err error){
    
    
    var person []*Person
    data,err := ioutil.ReadFile(filename)
    if err!=nil {
    
    
        return
    }
    err = msgpack.Unmarshal(data,&persons)        
}

将数据编码成json字符串

Go的json解析:Marshal与Unmarshal
参考URL: https://www.jianshu.com/p/3534532e06ed

type Stu struct {
    
    
    Name  string `json:"name"`
    Age   int
    HIgh  bool
    sex   string
    Class *Class `json:"class"`
}

type Class struct {
    
    
    Name  string
    Grade int
}

func main() {
    
    
    //实例化一个数据结构,用于生成json字符串
    stu := Stu{
    
    
        Name: "张三",
        Age:  18,
        HIgh: true,
        sex:  "男",
    }

    //指针变量
    cla := new(Class)
    cla.Name = "1班"
    cla.Grade = 3
    stu.Class=cla

    //Marshal失败时err!=nil
    jsonStu, err := json.Marshal(stu)
    if err != nil {
    
    
        fmt.Println("生成json字符串错误")
    }

    //jsonStu是[]byte类型,转化成string类型便于查看
    fmt.Println(string(jsonStu))
}

结果:

{
    
    "name":"张三","Age":18,"HIgh":true,"class":{
    
    "Name":"1班","Grade":3}}

只要是可导出成员(变量首字母大写),都可以转成json。因成员变量sex是不可导出的,故无法转成json。

如果变量打上了json标签,如Name旁边的 json:“name” ,那么转化成的json key就用该标签“name”,否则取变量名作为key,如“Age”,“HIgh”。

bool类型也是可以直接转换为json的value值。Channel, complex 以及函数不能被编码json字符串。当然,循环的数据结构也不行,它会导致marshal陷入死循环。

指针变量,编码时自动转换为它所指向的值,如cla变量。
(当然,不传指针,Stu struct的成员Class如果换成Class struct类型,效果也是一模一样的。只不过指针更快,且能节省内存空间。)

最后,强调一句:json编码成字符串后就是纯粹的字符串了。

demo2:
在这里插入图片描述
总结:json.Marshal(ki) 返回的是 json字符串对应的 字节数组。

json解析

json.Unmarshal不区分json字段 的大小写,只要字母一样即可,不区分大小写

json转换为map

package main
import (
    "encoding/json"
    "fmt"
)
//把请求包定义成一个结构体
type Requestbody struct {
    
    
    req string
}
//以指针的方式传入,但在使用时却可以不用关心
// result 是函数内的临时变量,作为返回值可以直接返回调用层
func (r *Requestbody) Json2map() (s map[string]interface{
    
    }, err error) {
    
    
    var result map[string]interface{
    
    }
    if err := json.Unmarshal([]byte(r.req), &result); err != nil {
    
    
        return nil, err
    }
    return result, nil
}
func main() {
    
    
    //json转map
    var r Requestbody
    r.req = `{"name": "xym","sex": "male"}`
    if req2map, err := r.Json2map(); err == nil {
    
    
        fmt.Println(req2map["name"])
        fmt.Println(req2map)
    } else {
    
    
        fmt.Println(err)
    }
}

编码工具json-to-go:json转换成go struct工具

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

该工具立即将JSON转换为GO类型定义。将左侧的JSON结构粘贴,并在右侧生成等效的GO类型!

猜你喜欢

转载自blog.csdn.net/inthat/article/details/106466166
今日推荐