Golang 处理 Json(一):编码

JSON 是一种数据格式描述语言。以 key 和 value 构成的哈系结构,类似 Javascript 中的对象,python 中的字典。通常 json 格式的 key 是字符串,其值可以是任意类型,字串,数字,数组或者对象结构。更多关于 Json 的可以访问 JSON 了解。

数据结构 map

json 源于 Javascript 的对象结构,golang 中有直接对应的数据结构 map,可是 golang 的 map 也是 key-value 结构,同时 struct 结构体也可以描述 json。当然,对于 json 的数据类型,go 也会有对象的结构所匹配。大致对应关系如下:

数据类型 JSON Golang
字串 string string
整数 number int64
浮点数 number flaot64
数组 arrary slice
对象 object struct
布尔 bool bool
空值 null nil

JSON 编码

基本结构编码

golang 提供了 encoding/json 的标准库用于编码 json。大致需要两步:

  1. 首先定义 json 结构体。
  2. 使用 Marshal 方法序列化。

定义结构体的时候,只有字段名是大写的,才会被编码到 json 当中。

type Account struct {
    Email string
    password string
    Money float64
}

func main() {
    account := Account{
        Email: "[email protected]",
        password: "123456",
        Money: 100.5,
    }

    rs, err := json.Marshal(account)
    if err != nil{
        log.Fatalln(err)
    }

    fmt.Println(rs)
    fmt.Println(string(rs))
}

可以看到输出如下,Marshal() 方法接受一个空接口的参数,返回一个 []byte 结构。小写命名的 password 字段没有被编码到 json 当中,生成的 json 结构字段和 Account 结构一致。

[123 34 69 109 97 105 108 34 58 34 114 115 106 50 49 55 64 103 109 97 105 108 46 99 111 109 34 44 34 77 111 110 101 121 34 58 49 48 48 46 53 125]
{"Email":"[email protected]","Money":100.5}

复合结构编码

相比字串,数字等基本数据结构,slice 切片,map 字典则是复合结构。这些结构编码也类似。不过 map 的 key 必须是字符串,而 value 必须是同一类型的数据。

type User struct {
    Name    string
    Age     int
    Roles   []string
    Skill   map[string]float64
}

func main() {

    skill := make(map[string]float64)

    skill["python"] = 99.5
    skill["elixir"] = 90
    skill["ruby"] = 80.0

    user := User{
        Name:"rsj217",
        Age: 27,
        Roles: []string{"Owner", "Master"},
        Skill: skill,
    }

    rs, err := json.Marshal(user)
    if err != nil{
        log.Fatalln(err)
    }
    fmt.Println(string(rs))
}

输出:

{
    "Name":"rsj217",
    "Age":27,
    "Roles":[
        "Owner",
        "Master"
    ],
    "Skill":{
        "elixir":90,
        "python":99.5,
        "ruby":80
    }
}

嵌套编码

slice 和 map 可以匹配 json 的数组和对象,当然,前提是对象的 value 是同类型的情况。更通用的做法,对象的 key 可以是 string,但是其值可以是多种结构。golang 可以通过定义结构体来实现这种构造:

type User struct {
	Name    string
	Age     int
	Roles   []string
	Skill   map[string]float64
	Account Account
}

type Account struct {
	Email string
	Money float64
}

func main() {
	skill := map[string]float64{
		"elixir":90,
        "python":99.5,
        "ruby":80,
	}
	account := Account{
		Email: "[email protected]",
		Money: 102.3,
	}

	user := User{
		Name:    "wenjianbao",
		Age:     30,
		Roles:   []string{"Owner", "Master"},
		Skill:   skill,
		Account: account,
	}

	js, err := json.Marshal(user)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(js))
}

输出:

{
    "Name":"wenjianbao",
    "Age":30,
    "Roles":[
        "Owner",
        "Master"
    ],
    "Skill":{
        "elixir":90,
        "python":99.5,
        "ruby":80
    },
    "Account":{
        "Email":"[email protected]",
        "Money":102.3
    }
}

通过定义嵌套的结构体 Account,实现了 key 与 value 不一样的结构。golang 的数组或切片,其类型也是一样的,如果遇到不同数据类型的数组,则需要借助空结构来实现:

type User struct {
	Name    string
	Age     int
	Roles   []string
	Skill   map[string]float64
	Account Account
	Extra   []interface{}
}

type Account struct {
	Email string
	Money float64
}

func main() {
	skill := map[string]float64{
		"elixir": 90,
		"python": 99.5,
		"ruby":   80,
	}
	account := Account{
		Email: "[email protected]",
		Money: 102.3,
	}
	extra := []interface{}{123, "Hello World"}

	user := User{
		Name:    "wenjianbao",
		Age:     30,
		Roles:   []string{"Owner", "Master"},
		Skill:   skill,
		Account: account,
		Extra:   extra,
	}

	js, err := json.Marshal(user)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(js))
}

输出:

{
    "Name":"wenjianbao",
    "Age":30,
    "Roles":[
        "Owner",
        "Master"
    ],
    "Skill":{
        "elixir":90,
        "python":99.5,
        "ruby":80
    },
    "Account":{
        "Email":"[email protected]",
        "Money":102.3
    },
    "Extra":[
        123,
        "Hello World"
    ]
}

使用空接口,也可以定义像结构体实现那种不同 value 类型的字典结构。当空接口没有初始化其值的时候,零值是 nil。编码成 json 就是 null

type User struct {
	Name    string
	Age     int
	Roles   []string
	Skill   map[string]float64
	Account Account

	Extra []interface{}
	Level map[string]interface{}
}

type Account struct {
	Email string
	Money float64
}

func main() {
	skill := map[string]float64{
		"elixir": 90,
		"python": 99.5,
		"ruby":   80,
	}
	account := Account{
		Email: "[email protected]",
		Money: 102.3,
	}

	level := make(map[string]interface{})
	level["web"] = "Good"
	level["server"] = 90
	level["tool"] = nil

	user := User{
		Name:    "wenjianbao",
		Age:     30,
		Roles:   []string{"Owner", "Master"},
		Skill:   skill,
		Account: account,
		Level:   level,
	}

	js, err := json.Marshal(user)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(js))
}

输出:

{
    "Name":"wenjianbao",
    "Age":30,
    "Roles":[
        "Owner",
        "Master"
    ],
    "Skill":{
        "elixir":90,
        "python":99.5,
        "ruby":80
    },
    "Account":{
        "Email":"[email protected]",
        "Money":102.3
    },
    "Extra":null,
    "Level":{
        "server":90,
        "tool":null,
        "web":"Good"
    }
}

可以看到 Extra返回的并不是一个空的切片,而是null。同时Level字段实现了向字典的嵌套结构。

时间: 2024-10-04 09:06:39

Golang 处理 Json(一):编码的相关文章

Go_14:GoLang中 json、map、struct 之间的相互转化

1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母必须为大写.请看下面的例子: package commontest import ( "testing" "encoding/json" ) type Person struct { name string age int } func TestStruct2Json(

Golang高性能json包:easyjson

简介 easyjson是什么呢? 根据官网介绍,easyjson是提供高效快速且易用的结构体structs<-->json转换包.easyjson并没有使用反射方式实现,所以性能比其他的json包该4-5倍,比golang 自带的json包快2-3倍. easyjson目标是维持生成去代码简单,以致于它可以轻松地进行优化或固定. 安装 go get -u github.com/mailru/easyjson/go install  github.com/mailru/easyjson/easy

golang的json操作

package main import ( "encoding/json" "fmt" "os" ) type ConfigStruct struct { Host string `json:"host"` Port int `json:"port"` AnalyticsFile string `json:"analytics_file"` StaticFileVersion int `

golang的json操作[转]

package main import (     "encoding/json"     "fmt"     "os" ) type ConfigStruct struct {     Host              string   `json:"host"`     Port              int      `json:"port"`     AnalyticsFile     str

golang的json序列化

json就是简单的数据交换格式,语法类似javascript的对象和列表,是最常见的后端和运行在网页上的js之间的通信格式. encoding: 编码json数据需要使用到Marshal()函数. func Marshal(v interface{}) ([]byte, error) type Message struct { Name string Body string Time int64 } m := Message{"Alice", "Hello", 12

golang time json mongodb 时间处理

golang 中解决前端time 输出,后端mongodb中时间存储. package mask import ( "fmt" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsontype" ) // Timestamp extension time type Timestamp struct { Time time.T

Python 2.7.9 Demo - JSON的编码、解码

#coding=utf-8 #!/usr/bin/python import json; dict = {}; dict['name'] = 'nick'; dict['say'] = 'hello world...'; dict['age'] = '20'; dict_json = repr(dict); print dict_json; dict_json_2 = json.dumps(dict); print dict_json_2; #coding=utf-8 #!/usr/bin/py

[笔记] Golang 处理JSON

1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 ) 7 8 /* 9 10 GO类型和JSON类型的对应关系 11 • bool 代表 JSON booleans, 12 • float64 代表 JSON numbers, 13 • string 代表 JSON strings, 14 • nil 代表 JSON null. 15 16 三方开源库: 17 https://github.com/bit

golang http json http://www.alexedwards.net/blog/golang-response-snippets

http://www.alexedwards.net/blog/golang-response-snippets https://gist.github.com/andreagrandi/97263aaf7f9344d3ffe6 https://talks.golang.org/2012/simple/webfront/main.go https://stevenwhite.com/building-a-rest-service-with-golang-2/