欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二十一、Json

程序员文章站 2022-07-07 19:50:36
...

1.介绍

在内存数据进行持久化存储或网络交换时常可采用 json 格式字符串,go 语言提供 json
包进行 json 序列化和反序列化
对于 Go 提供的基本类型和符合类型可以直接使用 json 包进行序列化和反序列化操作,
针对结构体可通过标签声明属性和 json 字符串的转换关系,标签名为 json,常用格式
为:
⚫ json:
默认形式,可省略,json 键名使用属性名,类型通过属性对应的类型
⚫ json:“key”
json 键名使用指定名称 key
⚫ json:"-"
忽略该属性
⚫ json:“key,type”
json 键名使用指定名称 key,类型使用指定类型 type
⚫ json:“key,omitempty”
json 键名使用指定名称 key,当值为零值时省略该属性
⚫ json:“key,type,omitempty”
json 键名使用指定名称 key,类型使用指定类型 type,当值为零值时省略该属性
⚫ json:",type"
类型使用指定类型 type
⚫ json:",omitempty"
值为零值时省略该属性

2.常用函数

Marshal: 用于将 go 语言的数据序列化为 json 字符串
Indent: 将 json 字符串进行格式化
UnMarshal: 用于 json 字符串反序列化为 go 语言的数据
MarshalIndent: 用于将 go 语言的数据序列化为格式化的 json 字符串
Valid: 验证是否为正确 json 字符串

3.Encoder 与 Decoder

Encoder 与 Decoder 是构建在流之上进行 JSON 序列化与反序列化,构造函数分别为
NewEncoder 和 NewDecoder,参数要求分别实现接口 io.Writer 和 io.Reader 的对象
Encoder.Encode 序列化
Decoder.Decode 反序列化

4.示例

(1)字符串转换

package main

import (
   "encoding/json"
   "fmt"
)

func main() {
   //json.Marshal()     序列化 内存=>字符串/字节切片
   //json.Unmarshal()   反序列化 字符串/字节切片  =>内存
   //转换json格式
   selice := []string{"aa","aaaa","aaaaaa"}
   bytes ,err :=  json.Marshal(selice)
   fmt.Printf("%v %v \n",string(bytes),err)
   //json转换 字符串切片
   var name []string
   err = json.Unmarshal(bytes,&name)
   fmt.Println(name)
   //字符串切片 转换json的时候格式化
   bytes ,err = json.MarshalIndent(name,"","\t")
   if err == nil {
      fmt.Println(string(bytes))
   }
   //验证是否可以转换为json
   fmt.Println(json.Valid([]byte("[aa aaaa aaaaaa]")))
}

(2)结构体转换

package main

import (
   "encoding/json"
   "fmt"
)
type Addr struct {
   No int `json:"no"`
   Street string `json:"street"`
}
//结构体要进行序列化或者反序列化 内部元素属性必须是公开的也就是大写
type User struct {
   ID int`json:"-"`  //这个表示忽略
   Name string
   Age int`json:"age,int,omitempty"`   //第一个表示属性名  第二个表示类型  第三个表示 如果是零值就忽略
   desc string
   Addr Addr `json:"addr"`
}

func main() {
   user :=User{
      ID:   1,
      Name: "b",
      Age:  0,
      desc: "c",
      Addr: Addr{
         No: 1,
         Street: "aa",
      },
   }
   bytes ,_ := json.MarshalIndent(user,"","\t")
   fmt.Println(string(bytes))
   var users User
   json.Unmarshal(bytes,&users)
   fmt.Println(users)
}

(3)自定义类型转换

package main

import (
   "encoding/json"
   "fmt"
)

//自定义类型json转换

const (
   Large = iota //large
   Medium     //medium
   Small        //small
)

type Size int

func (s Size)  MarshalText() ([]byte,error){
   switch s {
   case Large:
      return []byte("large"),nil
   case Medium:
      return []byte("medium"),nil
   case Small:
      return []byte("small"),nil
   default:
      return []byte("unknow"),nil
   }
}

func (s *Size) UnmarshalText(byte []byte) error{
   switch string(byte) {
   case "large":
      *s = Large
   case "medium":
      *s = Medium
   case "small":
      *s = Small
   default:
      *s = Small
   }
   return nil
}



func main() {
   var size Size = Medium
   bytes,_ := json.Marshal(size)
   fmt.Println(string(bytes))
   json.Unmarshal(bytes,&size)
   fmt.Println(size)


   sizes := []Size{Large,Large,Small,Medium}
   bytes,_ = json.Marshal(sizes)
   fmt.Println(string(bytes))
   var size02 []Size
   json.Unmarshal(bytes,&size02)
   fmt.Println(size02)
}