August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Go语言基础-序列化与反序列化
发布:2023年08月24日 | 作者:augustrush | 阅读量: 920

JSON序列化

json序列化是指,将语言中键值对类型的数据转换为json字符串

比如go语言中的结构体、map、数组、切片等,转换为json的格式被称为格式化

在Go中基础库中有一个叫encoding/json的包是用于处理json字符串的

func Marshal(v interface{}) ([]byte, error)

//Marshal函数接收的是一个空接口类型
//意思是我们可以将go的任意类型的数据传入进去
//而返回值是一个byte的切片,以及error

结构体序列化

package main

import (
    "encoding/json"
    "fmt"
)

type Monster struct{   //我们先定义一个结构体
    Name string
    Age int
    Birthady string
    Sal float64
    Skill string
}


func main(){
    monster := Monster{        //实例化结构体
        Name: "牛魔王",
        Age: 500,
        Birthady: "2011-11-11",
        Sal: 8000.0,
        Skill: "牛魔拳",
    }
    data,err := json.Marshal(monster)  //通过json包下的Marshal函数对结构体进行转换
    if err != nil{
        fmt.Printf("序列化错误 err=%v",err)
    }

    //输出序列化的结果
    fmt.Println(string(data))
}

返回

{"Name":"牛魔王","Age":500,"Birthady":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}

map序列化

package main

import (
    "encoding/json"
    "fmt"
)

func main(){
    //定义一个map
    var a map[string]interface{}
    a = make(map[string]interface{})
    a["name"] = "红孩儿"
    a["age"] = 30
    a["address"] = "火云洞"
    data,err := json.Marshal(a)     //将a这个map进行序列化
    if err != nil{
        fmt.Printf("序列化错误 err=%v",err)
    }
    fmt.Println(string(data))   
}

返回

{"address":"火云洞","age":30,"name":"红孩儿"}

map类型是无序的,所以结果略有不同

切片序列化

package main

import (
    "encoding/json"
    "fmt"
)

func main(){
    var slice []map[string]interface{}   //定义一个切片,声明值为空接口
    var m1 map[string]interface{}
    m1 = make(map[string]interface{})
    m1["name"] = "jack"
    m1["age"] = "7"
    m1["address"] = "北京"
    slice = append(slice,m1)  //将m1加入切片
    var m2 map[string]interface{}
    m2 = make(map[string]interface{})
    m2["name"] = "tom"
    m2["age"] = "20"
    m2["address"] = "墨西哥"
    slice = append(slice,m2)  //将m2加入切片
    data,err := json.Marshal(slice)     //将切片进行序列化操作
    if err != nil{
        fmt.Printf("序列化错误 err=%v",err)
    }
    fmt.Println(string(data))
}

返回:

[{"address":"北京","age":"7","name":"jack"},{"address":"墨西哥","age":"20","name":"tom"}]

### 序列化数组

package main

import (
    "encoding/json"
    "fmt"
)
var userInfo map[string]interface{}
var userArray [3]interface{}

func main() {
    userInfo = make(map[string]interface{})
    userInfo["name"] = "august"
    userInfo["age"] = 24
    userInfo["gender"] = "male"
    userArray[0] = userInfo
    userArray[1] = userInfo
    userArray[2] = userInfo
    fmt.Println(userArray)
    s_d, _ := json.Marshal(userArray)
    fmt.Println(string(s_d))
}

返回:

[{"age":24,"gender":"male","name":"august"},{"age":24,"gender":"male","name":"august"},{"age":24,"gender":"male","name":"august"}]

标签

我们上面序列化结构体的时候,实际上就是把字段的key作为json的key使用

但在浏览器中我们更希望接收到的是首字母小写的字段,为了不破坏结构体调用,可以使用标签

package main

import (
    "encoding/json"
    "fmt"
)
//定义一个结构体
type Monster struct{
    Name string `json:"xxx_name"` //我们在定义结构体的时候,设置好tag json的一个标签
    Age int     `json:"xxx_age"`  //这样在转换时,就会转换为小写
    Birthady string
    Sal float64
    Skill string
}

func main(){
    monster := Monster{
        Name: "牛魔王" ,
        Age: 500,
        Birthady: "2011-11-11",
        Sal: 8000.0,
        Skill: "牛魔拳",
    }
    data,err := json.Marshal(&monster)
    if err != nil{
        fmt.Printf("序列化错误 err=%v",err)
    }
    fmt.Println(string(data))
}

返回:

{"xxx_name":"牛魔王","xxx_age":500,"Birthady":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}

我们在结构体后面添加别名,这样在序列化时导出的就是别名的字段了

我们不能直接将字段定义为小写,这样会影响到其他的包进行调用

JSON反序列化

就是将我们上面转换的json,重新转换为我们go所使用的数据类型

func Unmarshal(data []byte, v interface{}) error

//传入的值是一个切片类型
//后面的v interface是指定我们用于接收json数据的结构体
//是否接收成功返回一个error的值

JSON转换为结构体

package main

import (
    "encoding/json"
    "fmt"
)
//定义一个结构体,必须要有这个结构体才能去反序列化到结构体
type Monster struct{
    Name string
    Age int
    Birthady string
    Sal float64
    Skill string
}
func main(){
    //我们将这个json写入到变量,不过因为他本身有双引号,这里通过反斜杠将双斜杠转义
    //在实际开发中,这个str的字符串是通过前端POST上传或者读取文件得到的
    str := "{\"Name\":\"牛魔王\",\"Age\":500,\"Birthady\":\"2011-11-11\",\"Sal\":8000,\"Skill\":\"牛魔拳\"}"

    var monster Monster       //定义一个结构体,去接收反序列化json的结果   
    err := json.Unmarshal([]byte(str),&monster)  //反序列化,通过[]byte(str)类型断言将str转换为切片
    if err != nil{
        fmt.Printf("unmarshal err=%v\n",err)
    }
    fmt.Println(monster)
}

返回:

{牛魔王 500 2011-11-11 8000 牛魔拳}

JSON转换为map

package main

import (
    "encoding/json"
    "fmt"
)
func main(){
    str := "{\"address\":\"火云洞\",\"age\":30,\"name\":\"红孩儿\"}"
    var a map[string]interface{}  //定义一个map,必须和要转换的json之前的数据类型相同
                              //反序列化时,Unmarshal已经封装了make动作,这里就不make了
    err := json.Unmarshal([]byte(str),&a)  //反序列化,必须传入&a才可使用
    if err != nil{
        fmt.Printf("unmarshal err=%v\n",err)
    }

    fmt.Printf("反序列化map后 a=%v",a)
}

返回:

map[address:火云洞 age:30 name:红孩儿]

JSON反序列化成切片

package main

import (
    "encoding/json"
    "fmt"
)
func unmarshalSclice(){
    str := "[{\"address\":\"北京\",\"age\":\"7\",\"name\":\"jack\"}," +
        "{\"address\":\"墨西哥\",\"age\":\"20\",\"name\":\"tom\"}]"
    var slice []map[string]interface{}   //定义一个切片,同样无需序列化

    err := json.Unmarshal([]byte(str),&slice)
    if err != nil{
        fmt.Printf("unmarshal err=%v\n",err)
    }

    fmt.Println(slice)
}

返回:

[map[address:北京 age:7 name:jack] map[address:墨西哥 age:20 name:tom]]

在反序列化一个Json字串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致



  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed