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。