十五、JSON处理

1、编码为JSON格式

  • 使用json.Marshal()函数可以对一组数据进行JSON格式的编码。
  • Go语言的大多数数据类型都可以转化为有效的JSON文本,但channel、complex和函数这几种类型除外。
  • 如果转化前的数据结构中出现指针,那么将会转化指针所指向的值,如果指针指向的是零值,那么null将作为转化后的结果输出。
  • 结构体会转化为JSON对象,并且只有结构体里边以大写字母开头的可被导出的字段才会被转化输出。
package main

import (
	"encoding/json"
	"fmt"
)

type Book struct {
	Title       string
	Authors     []string
	Publisher   string
	IsPublished bool
	Price       float64
}

func main() {
	//结构体
	gobook := Book{"Go语言编程", []string{"ZhangSan", "LiSi"}, "ituring.com.cn", true, 9.99}
	b, err := json.Marshal(gobook)
	if err != nil {
		fmt.Println(err)
	}
	//{"Title":"Go语言编程","Authors":["ZhangSan","LiSi"],"Publisher":"ituring.com.cn","IsPublished":true,"Price":9.99}
	fmt.Println(string(b))

	gomap := map[string]string{"zhangsan": "张三", "lisi": "李四", "wangwu": "王五"}
	m, err := json.Marshal(gomap)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(m)) //{"lisi":"李四","wangwu":"王五","zhangsan":"张三"}
}

2、解码JSON数据

  • 可以使用 json.Unmarshal()函数将 JSON格式的文本解码为 Go里边预期的数据结构。
  • 如果JSON中的字段在Go目标类型中不存在,在解码过程中会丢弃该字段。
  • 目标类型中不可被导出的私有字段(非首字母大写)将不会受到解码转化的影响。
package main

import (
	"encoding/json"
	"fmt"
)

type Book struct {
	Title       string
	Authors     []string
	Publisher   string
	IsPublished bool
	Price       float64
}

func main() {
	var book Book
	b := `{"Title":"Go语言编程","Authors":["ZhangSan","LiSi"],"Publisher":"ituring.com.cn","IsPublished":true,"Price":9.99}`
	err := json.Unmarshal([]byte(b), &book)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(book)           //{Go语言编程 [ZhangSan LiSi] ituring.com.cn true 9.99}
	fmt.Println(book.Title)     //Go语言编程
	fmt.Println(book.Publisher) //ituring.com.cn

	var mp map[string]string
	m := `{"lisi":"李四","wangwu":"王五","zhangsan":"张三"}`
	json.Unmarshal([]byte(m), &mp)
	fmt.Println(mp)             //map[zhangsan:张三 lisi:李四 wangwu:王五]
	fmt.Println(mp["lisi"])     //李四
	fmt.Println(mp["zhangsan"]) //张三
}

3、解码未知结构的JSON数据

  • 没有任何方法的空接口可以代表任何类型。换句话说,每一个类型其实都至少实现了一个空接口。
  • Go内建这样灵活的类型系统,向我们传达了一个很有价值的信息:空接口是通用类型。
  • 如果要解码一段未知结构的JSON,只需将这段JSON数据解码输出到一个空接口即可。
package main

import (
	"encoding/json"
	"fmt"
)

type Book struct {
	Title       string
	Authors     []string
	Publisher   string
	IsPublished bool
	price       float64
}

func main() {
	var r interface{}
	b := []byte(`{"Title":"Go语言编程","Authors":["ZhangSan","LiSi"],"Publisher":"ituring.com.cn","IsPublished":true,"Price":9.99}`)
	err := json.Unmarshal(b, &r) //最终r将会是一个键值对的 map[string]interface{} 结构
	if err != nil {
		fmt.Println(err)
	}
	gobook, ok := r.(map[string]interface{})
	if ok {
		for k, v := range gobook {
			switch v2 := v.(type) {
			case string:
				fmt.Println(k, "is string", v2)
			case int:
				fmt.Println(k, "is int", v2)
			case bool:
				fmt.Println(k, "is bool", v2)
			case []interface{}:
				fmt.Println(k, "is an array:")
				for i, iv := range v2 {
					fmt.Println(i, iv)
				}
			default:
				fmt.Println(k, "is another type not handle yet")
			}
		}
	}
}

4、JSON的流式读写

  • Go内建的encoding/json 包还提供Decoder和Encoder两个类型,用于支持JSON数据的流式读写
  • 使用Decoder 和Encoder对数据流进行处理可以应用得更为广泛些,比如读写 HTTP 连接、WebSocket或文件等
package main

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

func main() {
	//JSON数据的流式读写
	dec := json.NewDecoder(os.Stdin)  //编码、读
	enc := json.NewEncoder(os.Stdout) //解码、写

	var json map[string]interface{}
	//读入json
	if err := dec.Decode(&json); err != nil {
		log.Println(err)
	}

	for k, v := range json {
		fmt.Println(k, " = ", v)

		if k == "Authors" {
			json[k] = "事后诸葛亮"
		}
	}

	//写出json
	if err := enc.Encode(&json); err != nil {
		log.Println(err)
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值