20.1 JSON-JSON接口以及在Go语言中使用JSON

1. 简介

JSON即JavaScript对象表示法(JavaScript Object Notation),是一种用于存储和交换数据的格式,是一种可供人类阅读和理解的纯文本格式。

JSON既可以键值对的形式,也可以数组的形式,表示数据。

JSON最初是JavaScript的一个子集,但现在已然独立,为大多数语言所支持。

JSON已经取代XML,成为互联网上存储和交换数据的事实标准。

JSON以下面这种形式描述对象(一系列键值对组合):

  • {
  • "name": "George",

"age": 40,

"children": ["Bea", "Fin"]

}

2. JSON接口

近年来,互联网上出现了很多卓越的JSON格式的API (Application Programming Interface,应用编程接口)。

借助这些API,应用程序可以从作为数据交换平台的互联网上,获得海量的有关任何主题的数据。

API令应用开发者无须连接到数据库,就能请求并使用各种形式的数据资源。

  • 例如下面的JSON数据来自Dark Sky天气预报服务系统,通过json格式字符串描述了经纬度、时区、温度等内容。
    • {"latitude": 42.3601, "longitude": -71.0589, "timezone": "America/New_York",
    • "currently": {"time": 1509993277, "summary": "Drizzle", "icon": "rain",
    • "nearestStormDistance": 0, "precipIntensity": 0.0089, ...},
    • "minutely": {"summary": "Light rain stopping in 13 min., starting again 30 min. later.",
    • "icon": "rain", "data": [{...}, ...]},
    • "hourly": {"summary": ... }, ... }

3. 在Go语言中使用JSON

Go语言标准库通过encoding/json包提供对JSON数据的编码和解码操作。

JSON编码,即将Go语言数据类型的变量转换为JSON格式的字符串

  • 定义结构体类型
    • type Person struct { ... },结构体的字段名对应json的"键"
  • 创建结构体变量
    • p := Person{ ... }
  • 将结构体变量编码为JSON格式的字节切片
    • jb, err := json.Marshal(p)
  • 将JSON格式的字节切片转换为JSON格式的字符串
    • js := string(jb)
Go 复制代码
// 创建结构体
// 结构体可将多个不同类型的数据组织在一起,是一种绝佳的数据封装形式
package main
import "fmt"

type person struct {
    name    string
    age     int 
    hobbies []string
}
func main() {
    p := person{
        name:    "George",
        age:     40,
        hobbies: []string{"Cycling", "Cheese", "Techno"},
    }
    fmt.Printf("%+v\n", p)
}
// 打印输出:
{name:George age:40 hobbies:[Cycling Cheese Techno]} 
Go 复制代码
// 将结构体编码为JSON字符串
//         json.Marshal                string
// 结构体 -------------> JSON字节切片 ------> JSON字符串
package main

import (
    "encoding/json"
    "fmt"
    "log"
)

// Person with name, age and hobbies
type Person struct {
    Name    string
    Age     int 
    Hobbies []string
}
func main() {
    p := Person{
        Name:    "George",
        Age:     40,
        Hobbies: []string{
            "Cycling", "Cheese", "Techno"},
    }

    fmt.Printf("%+v\n", p)

	jb, err := json.Marshal(p)	//将结构体变量编码为JSON格式的字节切片
    if err != nil {
        log.Fatal(err)
    }

    js := string(jb)	// 将json字节切片转换为json字符串
    fmt.Println(js)
}
// 打印输出:
{Name:George Age:40 Hobbies:[Cycling Cheese Techno]}
{"Name":"George","Age":40,"Hobbies":["Cycling","Cheese","Techno"]}

默认情况下,JSON字符串中的键和值分别取自结构体中的字段名和字段值(大小写敏感)。

  • type Person struct {
  • Name string
  • Age int
  • Hobbies []string
  • }
  • {" Name ":"George"," Age ":40," Hobbies ":["Cycling","Cheese","Techno"]}

如果为结构体字段指定了JSON标签,则以标签文本作为JSON字符串的键。

  • type Person struct {

// 标签是以反引号包围的

Name string `json:" name "`

Age int `json:" age "`

Hobbies []string `json:" hobbies "`

}

****{"name ":"George"," age ":40," hobbies ":["Cycling","Cheese","Techno"]}

Go 复制代码
// 使用JSON标签
// 默认情况下,JSON字符串中的键和值分别取自结构体中的字段名和字段值,但
// 如果为结构体中的字段指定了JSON标签,则以标签文本作为JSON字符串的键
// 
// type 结构体 struct {
//     字段1 类型1 `json:"键1"` 
//     字段2 类型2 `json:"键2"` 
//     ... 
//     字段n 类型n `json:"键n"`
// }
package main

import (
    "encoding/json"
    "fmt"
    "log"
)
// Person with name, age and hobbies
type Person struct {
    Name    string   `json:"name"`
    Age     int      `json:"age"`
    Hobbies []string `json:"hobbies"`
}

func main() {
    p := Person{
        Name:    "George",
        Age:     40,
        Hobbies: []string{
            "Cycling", "Cheese", "Techno"},
    }
    fmt.Printf("%+v\n", p)
	jb, err := json.Marshal(p)
    if err != nil {
        log.Fatal(err)
    }

    js := string(jb)
    fmt.Println(js)
}
// 打印输出:
{Name:George Age:40 Hobbies:[Cycling Cheese Techno]}
{"name":"George","age":40,"hobbies":["Cycling","Cheese","Techno"]} 

默认情况下,结构体中的零值字段也会被编码到JSON字符串中。

  • type Person struct {
  • Name string `json:"name"`
  • Age int `json:"age"`
  • Hobbies []string `json:"hobbies"`
  • }

p:= Person{} // 使用默认零值初始化

    • 通过j son.Marshal( p ) 函数将结构体解析为json 字符如下:

{"name":"","age":0,"hobbies":[]}

在JSON标签中使用"omitempty"关键字,令编码器在编码时忽略零值字段。

  • type Person struct {
  • Name string `json:"name, omitempty "`
  • Age int `json:"age, omitempty "`
  • Hobbies []string `json:"hobbies, omitempty "`
  • }
  • {}
Go 复制代码
// 忽略空字段
// 默认情况下,结构体中的零值字段也会被编码到JSON字符串中,除非在其JSON
// 标签中使用了"omitempty"关键字,指示编码器在编码的过程中忽略零值字段
package main

import (
    "encoding/json"
    "fmt"
    "log"
)

// Person with name, age and hobbies
type Person struct {
    Name    string   `json:"name,omitempty"`
    Age     int      `json:"age,omitempty"`
    Hobbies []string `json:"hobbies,omitempty"`
}
func main() {
    p := Person{}
    fmt.Printf("%+v\n", p)

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

    js := string(jb)
    fmt.Println(js)
}
// 打印输出:
{Name: Age:0 Hobbies:[]}
{} 
相关推荐
南宫理的日知录几秒前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
Mephisto.java4 分钟前
【大数据学习 | kafka高级部分】kafka的kraft集群
大数据·sql·oracle·kafka·json·hbase
Mephisto.java6 分钟前
【大数据学习 | kafka高级部分】kafka的文件存储原理
大数据·sql·oracle·kafka·json
逊嘘17 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
Half-up20 分钟前
C语言心型代码解析
c语言·开发语言
Source.Liu41 分钟前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng41 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马44 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng1 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
Jacob程序员1 小时前
java导出word文件(手绘)
java·开发语言·word