Go JSON
最后修改日期:2025 年 5 月 4 日
在本文中,我们将展示如何在 Golang 中处理 JSON 数据。
JSON
JSON(JavaScript Object Notation)是一种广泛使用的轻量级数据交换格式,可促进结构化数据交换。JSON 旨在易于人类阅读,同时易于机器解析和生成,已成为 Web 开发、API 和配置文件中数据序列化的标准。
JSON 的官方 Internet 媒体类型为 application/json,确保不同系统之间数据处理的一致性。JSON 文件通常使用 .json 文件名扩展名。
Go 中的 JSON
Go 通过 encoding/json 包提供了对 JSON 的内置支持,该包提供了高效的 JSON 数据编码和解码函数。一些关键操作包括
json.Marshal(v)- 将 Go 数据结构转换为 JSON 格式。json.Unmarshal(data, &v)- 将 JSON 数据解析到 Go 数据结构中。json.NewEncoder(w).Encode(v)- 直接将 JSON 输出写入写入器(例如,文件或 HTTP 响应)。json.NewDecoder(r).Decode(&v)- 从输入流读取并解码 JSON。
JSON 在现代软件开发中起着至关重要的作用,它能够实现应用程序和服务之间的无缝通信。其简洁性以及 Go 的高效处理机制,使其成为结构化数据表示的理想选择。
Go 编码为 JSON
Marshal 函数将数据编码为 JSON。
package main
import (
"encoding/json"
"fmt"
"log"
)
type User struct {
Id int
Name string
Occupation string
}
func main() {
u1 := User{1, "John Doe", "gardener"}
json_data, err := json.Marshal(u1)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(json_data))
users := []User{
{Id: 2, Name: "Roger Roe", Occupation: "driver"},
{Id: 3, Name: "Lucy Smith", Occupation: "teacher"},
{Id: 4, Name: "David Brown", Occupation: "programmer"},
}
json_data2, err := json.Marshal(users)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(json_data2))
}
在代码示例中,我们将 Go 结构体和结构体切片转换为 JSON 格式。
type User struct {
Id int
Name string
Occupation string
}
我们声明 User 结构体。
u1 := User{1, "John Doe", "gardener"}
我们创建结构体实例。
json_data, err := json.Marshal(u1)
我们使用 Marshal 将 u1 结构体编码为 JSON。
fmt.Println(string(json_data))
由于 json_data 是一个字节数组,我们使用 string 函数将其转换为字符串。
users := []User{
{Id: 2, Name: "Roger Roe", Occupation: "driver"},
{Id: 3, Name: "Lucy Smith", Occupation: "teacher"},
{Id: 4, Name: "David Brown", Occupation: "programmer"},
}
我们有一个用户切片。
json_data2, err := json.Marshal(users)
我们使用 Marshal 编码用户切片。
fmt.Println(string(json_data2))
我们打印编码后的切片。
$ go run encoding.go
{"Id":1,"Name":"John Doe","Occupation":"gardener"}
[{"Id":2,"Name":"Roger Roe","Occupation":"driver"},{"Id":3,"Name":"Lucy Smith","Occupation":"teacher"},
{"Id":4,"Name":"David Brown","Occupation":"programmer"}]
Go 解码为 JSON
Unmarshal 函数将 JSON 数据解码为 Go 值。
package main
import (
"encoding/json"
"fmt"
"log"
)
type User struct {
Id int
Name string
Occupation string
}
func main() {
var u1 User
data := []byte(`{
"Id" : 1,
"Name": "John Doe",
"Occupation": "gardener"
}`)
err := json.Unmarshal(data, &u1)
if err != nil {
log.Fatal(err)
}
fmt.Println("Struct is:", u1)
fmt.Printf("%s is a %s.\n", u1.Name, u1.Occupation)
var u2 []User
data2 := []byte(`
[
{"Id":2,"Name":"Roger Roe","Occupation":"driver"},
{"Id":3,"Name":"Lucy Smith","Occupation":"teacher"},
{"Id":4,"Name":"David Brown","Occupation":"programmer"}
]`)
err2 := json.Unmarshal(data2, &u2)
if err2 != nil {
log.Fatal(err2)
}
for i := range u2 {
fmt.Println(u2[i])
}
}
我们将 JSON 字符串解码为 Go 结构体和结构体切片。
data := []byte(`{
"Id" : 1,
"Name": "John Doe",
"Occupation": "gardener"
}`)
我们有一个 JSON 对象,它被转换为字节。
err := json.Unmarshal(data, &u1)
我们使用 Unmarshal 将 JSON 解码到结构体中,形成 u1 结构体。
var u2 []User
我们声明一个 User 结构体切片。
data2 := []byte(`
[
{"Id":2,"Name":"Roger Roe","Occupation":"driver"},
{"Id":3,"Name":"Lucy Smith","Occupation":"teacher"},
{"Id":4,"Name":"David Brown","Occupation":"programmer"}
]`)
这是一个要解码为 Go 切片的 JSON 数组。
err2 := json.Unmarshal(data2, &u2)
我们使用 Unmarshal 将 JSON 数组解码为 Go 切片。
for i := range u2 {
fmt.Println(u2[i])
}
我们逐个打印解码后的 JSON 数组用户。
$ go run decoding.go
Struct is: {1 John Doe gardener}
John Doe is a gardener.
{2 Roger Roe driver}
{3 Lucy Smith teacher}
{4 David Brown programmer}
Go JSON 美化打印
可以使用 MarshalIndent 函数美化打印输出。
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
birds := map[string]interface{}{
"sounds": map[string]string{
"pigeon": "coo",
"eagle": "squak",
"owl": "hoot",
"duck": "quack",
"cuckoo": "ku-ku",
"raven": "cruck-cruck",
"chicken": "cluck",
"rooster": "cock-a-doodle-do",
},
}
data, err := json.MarshalIndent(birds, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
}
在代码示例中,我们有一个鸟叫声的 map。输出使用 MarshalIndent 进行美化打印。
$ go run pretty_print.go
{
"sounds": {
"chicken": "cluck",
"cuckoo": "ku-ku",
"duck": "quack",
"eagle": "squak",
"owl": "hoot",
"pigeon": "coo",
"raven": "cruck-cruck",
"rooster": "cock-a-doodle-do"
}
}
我们可以看到输出是缩进的,因此更易读。
Go 从文件读取 JSON
下一个示例从文件中读取 JSON 数据。
[
{
"name": "John Doe",
"occupation": "gardener",
"born": "1992-03-02"
},
{
"name": "Brian Flemming",
"occupation": "teacher",
"born": "1967-11-22"
},
{
"name": "Lucy Black",
"occupation": "accountant",
"born": "1995-04-07"
},
{
"name": "John Doe",
"occupation": "gardener",
"born": "1972-08-30"
}
]
这是 data.json 文件。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
)
type User struct {
Name string
Occupation string
Born string
}
func main() {
filename, err := os.Open("data.json")
if err != nil {
log.Fatal(err)
}
defer filename.Close()
data, err := ioutil.ReadAll(filename)
if err != nil {
log.Fatal(err)
}
var result []User
jsonErr := json.Unmarshal(data, &result)
if jsonErr != nil {
log.Fatal(jsonErr)
}
fmt.Println(result)
}
该示例从文件中读取 JSON 数据并将其解码为 user 结构体切片。
$ go run read_json.go
[{John Doe gardener 1992-03-02} {Brian Flemming teacher 1967-11-22}
{Lucy Black accountant 1995-04-07} {John Doe gardener 1972-08-30}]
Go JSON HttpClient
net/http 包提供了 HTTP 客户端和服务器实现。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
type Astronaut struct {
Name string
Craft string
}
type people struct {
Number int
People []Astronaut
Message string
}
func main() {
url := "http://api.open-notify.org/astros.json"
var netClient = http.Client{
Timeout: time.Second * 10,
}
res, err := netClient.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Println(body)
if err != nil {
log.Fatal(err)
}
astros := people{}
jsonErr := json.Unmarshal(body, &astros)
if jsonErr != nil {
log.Fatal(jsonErr)
}
fmt.Println(astros)
}
该示例使用内置的 Go HTTP 客户端从 Web 服务读取数据。我们向一个服务发出 GET 请求,该服务返回国际空间站宇航员的数据。
$ go run astros.go
{3 [{Chris Cassidy ISS} {Anatoly Ivanishin ISS} {Ivan Vagner ISS}] success}
此时,空间站上有三名宇航员。
来源
在本文中,我们研究了 Golang 中的 JSON。