1. Marshal()
Syntax: func Marshal (v interface {}) ([]byte , error )
Man: 将Go中数据类型转换为 json 字符串的字节切片
2. Unmarshal()
Syntax: func Unmarshal (data []byte , v interface {}) error
Man: 反序列化json字符串
3. Indent()
Syntax: func Indent (dst *bytes.Buffer, src []byte , prefix, indent string ) error
Man: 缩进显示json字符串
4. Compact()
Syntax: func Compact (dst *bytes.Buffer, src []byte ) error
Man: 压缩无效空白符
1.2. json序列化
序列化中需要注意的点:
因为是调用 json.Mashal()
,如果结构体字段使用小写将因为不可导出,而无法完成序列化。
json.Mashal()
可以接收指针,因此实际操作中,都是传递指针而不是值
如果要对结构体中字段名和json中不一致,需要在结构体定义时指定json中显示的名称
1.2.1. 序列化基本案例
Id和Name有明确指定 json 序列化后的字段名,因此按小写显示
Hobby中的describe字段小写开头,因此不可导出,在json序列化后的结果中不可见
package main
import (
"encoding/json"
"fmt"
type Student struct {
Id int `json:"id"`
Name string `json:"name"`
Hobby []Hobby
type Hobby struct {
Name string
describe string
func main () {
var s0 = Student{
Id: 10001 ,
Name: "张三" ,
Hobby: []Hobby{
Name: "游泳" ,
describe: "游泳。。。。" ,
Name: "钓鱼" ,
describe: "台钓" ,
ret, err := json.Marshal(&s0)
if err != nil {
fmt.Println("序列化失败" )
return
fmt.Println(string (ret))
[root@heyingsheng models ]# go run json/marshal.go
{"id" :10001 ,"name" :"张三" ,"Hobby" :[{"Name" :"游泳" },{"Name" :"钓鱼" }]}
1.2.2. 格式化json
package main
import (
"bytes"
"encoding/json"
"fmt"
"strings"
func main () {
var str = `{"id":10001,"name":"张三","Hobby":[{"Name":"游泳"},{"Name":"钓鱼"}]}`
var s = bytes.Buffer{}
err := json.Indent(&s, []byte (str), " " , "\t" )
if err != nil {
fmt.Println("格式化失败,err=" ,err)
return
ret := s.String()
fmt.Println(ret)
fmt.Println(strings.Repeat("##" , 20 ))
res := bytes.Buffer{}
err = json.Compact(&res, []byte (ret))
if err != nil {
fmt.Println("格式化失败,err=" ,err)
return
fmt.Println(res.String())
[root@heyingsheng models ]# go run json/json.go
"id" : 10001 ,
"name" : "张三" ,
"Hobby" : [
"Name" : "游泳"
"Name" : "钓鱼"
########################################
{"id" :10001 ,"name" :"张三" ,"Hobby" :[{"Name" :"游泳" },{"Name" :"钓鱼" }]}
1.3. json反序列化
1.3.1. 简单反序列化
package main
import (
"encoding/json"
"fmt"
type User struct {
Name string `json:"name"`
Class []string `json:"class"`
func main () {
str := `{"10001": {"name": "张三", "class": ["物理","化学","生物"]}}`
var user01 map [string ]User
if err := json.Unmarshal([]byte (str), &user01); err != nil {
fmt.Println("反序列化失败,err=" , err)
return
fmt.Printf("type:%T, value:%v\n" , user01, user01)
fmt.Println(user01["10001" ].Class[0 ])
[root@heyingsheng models]# go run json/unmarshal.go
type :map [string ]main.User, value:map [10001 :{张三 [物理 化学 生物]}]
1.3.2. 使用空接口接收数据
空接口可以接收任何结构的json字符串,但是非常难以转换为可操作的go语言数据类型,因为涉及到类型的断言!
package main
import (
"encoding/json"
"fmt"
type User struct {
Name string `json:"name"`
Class []string `json:"class"`
func main () {
str := `{"10001": {"name": "张三", "class": ["物理","化学","生物"]}}`
var user01 interface {}
if err := json.Unmarshal([]byte (str), &user01); err != nil {
fmt.Println("反序列化失败,err=" , err)
return
fmt.Printf("type:%T, value:%v\n" , user01, user01)
if user, ok := user01.(map [string ]interface {}); ok {
fmt.Printf("type:%T, value:%v\n" , user["10001" ], user["10001" ])
[root@heyingsheng models]# go run json/unmarshal.go
type :map [string ]interface {}, value:map [10001 :map [class:[物理 化学 生物] name:张三]]
type :map [string ]interface {}, value:map [class:[物理 化学 生物] name:张三]
1.4. json的tag
1.4.1. 忽略字段
type User struct {
Name string `json:"name"`
UID string `json:"uid"`
Address string `json:"-"`
Password string `json:"password,omitempty"`
Phone `json:"phone"`
*Score `json:"score,omitempty"`
type Phone struct {
TelPhone string `json:"tel_phone,omitempty"`
Mobile string `json:"mobile,omitempty"`
type Score struct {
MathScore int `json:"math_score"`
MusicScore int `json:"music_score"`
func main () {
user01 := User{
Name: "ZhangSan" ,
UID: "0001" ,
Address: "南京" ,
Password: "" ,
ret, _ := json.Marshal(user01)
fmt.Println(string (ret))
[root@duduniao json ]# go run main.go
{"name" :"ZhangSan" ,"uid" :"0001" ,"phone" :{}}
1.4.2. 类型转换
在开发中,经常会出现服务调用接口,要求传递json中value为字符串,而代码结构体中为 bool 或者 int等其它类型。这种需求可以通过自定义的方法来实现转换,但是也有根据简单的方法,就是使用 tag 处理。
type Student struct {
Name string `json:"name"`
Age int8 `json:"age,string"`
IsAdmin bool `json:"is_admin,string"`
func main () {
s1 := Student{
"张三" ,
int8 (18 ),
false ,
ret, _ := json.Marshal(s1)
fmt.Println(string (ret))
fmt.Println(strings.Repeat("--" , 20 ))
str := `{"name":"李四","age":"39","is_admin":"true"}`
_ = json.Unmarshal([]byte (str), &s1)
fmt.Printf("%#v\n" , s1)
[root@duduniao json] # go run main .go
{"name":"张三" ,"age" :"18" ,"is_admin" :"false" }
----------------------------------------
main .Student {Name:"李四" , Age:39 , IsAdmin:true}
2. 使用simpleJson处理json
在对象序列化为 json 字符串时,或者将json对象反序列化并赋值给一个结构体指针,这两种场景很适合使用标准库中得 json 包,但是如果只是从现有得 json 中某一些字段得值,那么可以考虑使用 simplejson 的链式调用完成处理。
2.1. simplejson常用方法
# "github.com /bitly/go-simplejson"
1 . Json 结构体
type Json struct {
2 . 构造函数
func NewJson (body []byte) (*Json, error)
3 . 从 io.Reader 接口构造 Json对象
func NewFromReader (r io.Reader) (*Json, error)
4 . 断言相关的方法
func (j *Json) String () (string, error)
func (j *Json) Int () (int, error)
func (j *Json) Int64 () (int64, error)
func (j *Json) Uint64 () (uint64, error)
func (j *Json) Bool () (bool, error)
func (j *Json) Bytes () ([]byte, error)
func (j *Json) StringArray () ([]string, error)
func (j *Json) Interface () interface{}
func (j *Json) Map () (map[string]interface{}, error)
func (j *Json) Array () ([]interface{}, error)
5 . 保证返回指定类型的结果, args 设定默认值
func (j *Json) MustInt (args ...int) int
func (j *Json) MustString (args ...string) string
func (j *Json) MustFloat64 (args ...float64) float64
func (j *Json) MustBool (args ...bool) bool
func (j *Json) MustStringArray (args ...[]string) [] string
func (j *Json) MustMap (args ...map[string]interface{}) map[string] interface{}
func (j *Json) MustArray (args ...[]interface{}) [] interface{}
6 . 在map类型中,根据key取值
func (j *Json) Get (key string) *Json
7 . 更新json
func (j *Json) Del (key string)
func (j *Json) Set (key string, val interface{})
8 . 序列化
func (j *Json) Encode () ([]byte, error)
func (j *Json) EncodePretty () ([]byte, error)
2.2. 案例
** 测试的 Json 字符串如下 **
"deploy_type" : "task" ,
"uniqid" : "task-01" ,
"labels" : {
"deploy_type" : "db"
"callback_url" : "https://xxx.xxx.xxx" ,
"tasks" : [
"cluster_type" : "vm_cluster" ,
"deploy_type" : "vm_cluster" ,
"action" : "create" ,
"labels" : {
"deploy_type" : "cluster"
"uniqid" : "cluster01" ,
"name" : "cluster01" ,
"options" : {
"cadvisor" : true
2.2.1. 取值
func main() {
sJson, err : = simplejson.NewJson([ ] byte(str))
if err != nil {
fmt.Printf("New json failed, err:%s\n" , err.Error())
return
res1 : = sJson.Get("labels" ).Get("deploy_type" ).MustString("null" )
tmp1, _ : = json.Marshal(sJson.Get("tasks" ).MustArray()[ 0 ] )
tmp2, _ : = simplejson.NewJson(tmp1)
res2 : = tmp2.Get("labels" ).Get("deploy_type" ).MustString()
fmt.Printf("res1:%s,res2:%s\n" , res1, res2)
2.2.2 修改值
func main () {
sJson, err := simplejson.NewJson([]byte (str))
if err != nil {
fmt.Printf("New json failed, err:%s\n" , err.Error())
return
sJson.Del("tasks" )
res1, _:= sJson.EncodePretty()
fmt.Println(string (res1))
sJson.Set("labels" , false )
res2, _:= sJson.EncodePretty()
fmt.Println(string (res2))
复制代码
1.8w
ecnatsiDehToG
JavaScript