json包可以实现json的编码和解码,就是将json字符串转换为struct,或者将struct转换为json。
一 核心函数
1.1 Marshal
func Marshal(v interface{}) ([]byte, error)
将struct编码成json,可以接收任意类型
- 布尔型转换为 JSON 后仍是布尔型,如true -> true
- 浮点型和整数型转换后为JSON里面的常规数字,如 1.23 -> 1.23
- 字符串将以UTF-8编码转化输出为Unicode字符集的字符串,特殊字符比如<将会被转义为\u003c
- 数组和切片被转换为JSON 里面的数组,[]byte类会被转换为base64编码后的字符串,slice的零值被转换为null
- 结构体会转化为JSON对象,并且只有结构体里边以大写字母开头的可被导出的字段才会被转化输出,而这些可导出的字段会作为JSON对象的字符串索引
-
转化一个map 类型的数据结构时,该数据的类型必须是
map[string]T
(T 可以是encoding/json 包支持的任意数据类型)
实例演示:
① 结构体转换为json
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
Email string
}
func main() {
p := Person{
Name: "Psych",
Age: 20,
Email: "Psych@mail.com",
}
b, _ := json.Marshal(p)
fmt.Printf("b: %v\n", string(b))
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
b: {"Name":"Psych","Age":20,"Email":"Psych@mail.com"}
[Done] exited with code=0 in 0.965 seconds
② 解析嵌套类型
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
Email string
Parent []string
}
func main() {
p := Person{
Name: "Psych",
Age: 20,
Email: "Psych@mail.com",
Parent: []string{"Daddy", "Mom"},
}
b, _ := json.Marshal(p)
fmt.Printf("b: %v\n", string(b))
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
b: {"Name":"Psych","Age":20,"Email":"Psych@mail.com","Parent":["Daddy","Mom"]}
[Done] exited with code=0 in 1.018 seconds
1.2 Unmarshal
func Unmarshal(data []byte, v interface{}) error
将json转码为struct结构体
这个函数会把传入的 data 作为一个JSON来进行解析,解析后的数据存储在参数 v 中。这个参数 v 也是任意类型的参数(但一定是一个类型的指针),原因是我们在是以此函数进行JSON 解析的时候,这个函数不知道这个传入参数的具体类型,所以它需要接收所有的类型。
实例演示:
① json转换为结构体
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
Email string
}
func main() {
b := []byte(`{"Name":"Psych","Age":20,"Email":"Psych@mail.com"}`)
var m Person
json.Unmarshal(b, &m)
fmt.Printf("m: %v\n", m)
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
m: {Psych 20 Psych@mail.com}
[Done] exited with code=0 in 1.045 seconds
② 解析嵌套类型
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
Email string
Parent []string
}
func main() {
b := []byte(`{"Name":"Psych","Age":20,"Email":"Psych@mail.com","Parents":["Daddy","Mon"]}`)
var m map[string]interface{}
json.Unmarshal(b, &m)
fmt.Printf("m: %v\n", m)
for k, v := range m {
fmt.Printf("k: %v v: %v\n", k, v)
}
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
m: map[Age:20 Email:Psych@mail.com Name:Psych Parents:[Daddy Mon]]
k: Name v: Psych
k: Age v: 20
k: Email v: Psych@mail.com
k: Parents v: [Daddy Mon]
[Done] exited with code=0 in 1.01 seconds
二 核心结构
2.1 Decoder
type Decoder struct {
// contains filtered or unexported fields
}
从输入流读取并解析json,应用于
io流Reader Writer可以扩展到http websocket等场景
实例演示:
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
f, _ := os.Open("a.json")
defer f.Close()
d := json.NewDecoder(f)
var v map[string]interface{}
d.Decode(&v)
fmt.Printf("v: %v\n", v)
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
v: map[Age:20 Email:Psych@mail.com Name:Psych Parent:[Daddy Mom]]
[Done] exited with code=0 in 0.956 seconds
其中a.json文件内容为:
{"Name":"Psych","Age":20,"Email":"Psych@mail.com","Parent":["Daddy","Mom"]}
2.2 Encoder
type Encoder struct {
// contains filtered or unexported fields
}
写json到输出流,应用于
io流Reader Writer可以扩展到http websocket等场景
实例演示①
package main
import (
"encoding/json"
"os"
)
type Person struct {
Name string
Age int
Email string
Parent []string
}
func main() {
p := Person{
Name: "Psych",
Age: 20,
Email: "Psych@mail.com",
Parent: []string{"Daddy", "Mom"},
}
f, _ := os.OpenFile("a.json", os.O_WRONLY, 077)
defer f.Close()
d := json.NewEncoder(f)
d.Encode(p)
}
运行之后的a.json为(原文件内容为空):
{"Name":"Psych","Age":20,"Email":"Psych@mail.com","Parent":["Daddy","Mom"]}
实例演示②
package main
import (
"encoding/json"
"fmt"
"log"
"os"
)
func test() {
// dec := json.NewDecoder(os.Stdin)
f, _ := os.Open("a.json")
dec := json.NewDecoder(f)
enc := json.NewEncoder(os.Stdout)
for {
var v map[string]interface{}
if err := dec.Decode(&v); err != nil {
log.Println(err)
return
}
fmt.Printf("v: %v\n", v)
if err := enc.Encode(&v); err != nil {
log.Println(err)
}
}
}
func main() {
test()
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
v: map[Age:20 Email:Psych@mail.com Name:Psych Parent:[Daddy Mom]]
{"Age":20,"Email":"Psych@mail.com","Name":"Psych","Parent":["Daddy","Mom"]}
2022/07/14 17:55:30 EOF
[Done] exited with code=0 in 1.016 seconds