大多数现代应用程序需要在多个服务之间进行通信,而JSON是在网络上存储和传输数据的最流行的符号之一。在这篇文章中,我们将探讨如何在Go中使用JSON,这是一种流行的开源语言。
让我们开始吧!
JSON简介
JSON,即JavaScript对象符号,是一种用于存储、发送和接收信息的流行文本格式。由于JSON的结构简单,使用有序列表格式化为键值对,因此很容易编写和理解。
JSON是独立于语言的,这意味着它可以与任何编程语言一起使用。许多语言都有对JSON的内置支持。
让我们通过一个例子来看看JSON格式是什么样子的!在下面的代码块中,JSON对象代表一个网络应用的用户。
{
"firstname": "Mohit",
"lastname": "Khare",
"id": "mkfeuhrer",
"age": "24",
"gender": "male",
"preferred_topics": ["startups", "books", "chess", "blogging"],
"social_links": [
{
"site": "twitter",
"url": "https://twitter.com/mkfeuhrer"
}
]
}
根据JSON格式模式的定义方式,JSON的键必须是一个字符串。然而,值可以是一个字符串,一个对象,或一个字符串或对象的列表。
在Go中读取JSON文件
将上面代码块中的JSON对象保存到一个名为user.json 的文件中。我们将使用ioutil包中的ReadFile 来读取JSON文件并打印数据。
package main
import (
"fmt"
"io/ioutil"
)
func ReadJSON(filename string) ([]byte, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println("Error reading user.json", err)
return nil, err
}
fmt.Println("Success reading user.json")
return data, nil
}
func main() {
data, err := ReadJSON("user.json")
if err != nil {
return
}
fmt.Println("Content of user.json:")
fmt.Println(string(data))
}
上面的代码的输出如下。
Success reading user.json
Content of user.json:
{
"firstname": "Mohit",
"lastname": "Khare",
"id": "mkfeuhrer",
"age": "24",
"gender": "male",
"preferred_topics": [
"startups",
"books",
"chess"
],
"social_links": [
{
"site": "twitter",
"url": "https://twitter.com/mkfeuhrer"
}
]
}
在Go结构中解码JSON
现在我们可以读取JSON文件了,我们将把它解析为Go结构。您不能直接对JSON数据执行Go操作。相反,您必须将JSON数据映射到Go结构中,使其能够执行其他操作。
package jsonGo中提供了Unmarshal 函数,帮助我们将数据解析为结构体。
func Unmarshal(data []byte, v interface{}) error
Unmarshal 要求数据为字节数组,以便将其解析为一个接口。让我们创建一个结构来读取上面定义的用户数据。
// parse social link object
type SocialLink struct {
Site string `json:"site"`
URL string `json:"url"`
}
// parse user object
type User struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
ID string `json:"id"`
Age string `json:"age"`
Gender string `json:"gender"`
PreferredTopics []string `json:"preferred_topics"`
SocialLinks []SocialLink `json:"social_links"`
}
现在,我们将把JSON解析到这个结构中。
func DecodeJSON(data []byte, user *User) {
err := json.Unmarshal(data, user)
if err != nil {
fmt.Println("Error parsing JSON", err)
}
fmt.Println(*user)
}
// We call this function with the data and user Object
var user User
DecodeJSON(data, &user)
从Go结构中编码JSON
我们还想从Go应用程序中写入JSON数据,因此让我们将创建的结构转换为JSON数据。Go 的package json 提供了Marshal 函数来帮助将结构编码为 JSON 数据。
func Marshal(v interface{}) ([]byte, error)
Marshal 需要一个接口,我们将从中编码JSON数据。让我们把我们的User 对象编码成JSON。
func EncodeJSON(user *User) {
data, err := json.Marshal(user)
if err != nil {
fmt.Println("Error parsing JSON", err)
}
fmt.Println(string(data))
}
// We call this function with the data and user Object
user := User {
Firstname: "John",
Lastname: "Doe",
ID: "john",
Age: "30",
Gender: "male",
SocialLinks: []SocialLink{
{
Site: "twitter",
URL: "https://twitter.com/john",
},
},
}
EncodeJSON(data, &user)
上面的函数将打印JSON数据。
{
"firstname": "John",
"lastname": "Doe",
"id": "john",
"age": "30",
"gender": "male",
"preferred_topics": null,
"social_links": [
{
"site": "twitter",
"url": "https://twitter.com/john"
}
]
}
仔细注意preferred_topics 字段是null ,因为我们的用户对象没有为这个属性分配一个值。现在,让我们来学习如何跳过空字段。
Go中的JSON标签
当我们定义结构时,我们使用了一些JSON标签。标签帮助我们通过省略空字段或空字段来控制属性的关键。
让我们看看标签的一个例子在下面的代码块中,我们将定义Firstname 属性以使用JSON中的"first name" 关键。如果PreferredTopics 是空的,我们将从该对象中省略。
PreferredTopics []string `json:"preferred_topics,omitempty"`
当我们对JSON进行编码/解码时,我们将简单地忽略Age 。
Age int `json:"-"`
当一个值在我们的结构中是可选的,我们通常使用omitempty 。在我们的用户例子中,如果用户的lastname 不存在,我们可以管理,但我们不能将omitempty 添加到id 。
你完成的代码将看起来像下面的代码块。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type SocialLink struct {
Site string `json:"site"`
URL string `json:"url"`
}
type User struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname,omitempty"`
ID string `json:"id"`
Age string `json:"age,omitempty"`
Gender string `json:"gender,omitempty"`
PreferredTopics []string `json:"preferred_topics,omitempty"`
SocialLinks []SocialLink `json:"social_links,omitempty"`
}
func ReadJSON(filename string) ([]byte, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println("Error reading user.json", err)
return nil, err
}
fmt.Println("Success reading user.json")
return data, nil
}
func DecodeJSON(data []byte, user *User) {
err := json.Unmarshal(data, user)
if err != nil {
fmt.Println("Error parsing JSON", err)
}
fmt.Println(*user)
}
func EncodeJSON(user *User) {
data, err := json.Marshal(user)
if err != nil {
fmt.Println("Error parsing JSON", err)
}
fmt.Println(string(data))
}
func main() {
data, err := ReadJSON("user.json")
if err != nil {
return
}
fmt.Println("Content of user.json:")
fmt.Println(string(data))
var user User
fmt.Println("\nDecode JSON data to user struct:")
DecodeJSON(data, &user)
// define new user
user2 := User{
Firstname: "John",
Lastname: "Doe",
ID: "john",
Age: "30",
Gender: "male",
SocialLinks: []SocialLink{
{
Site: "twitter",
URL: "https://twitter.com/john",
},
},
}
fmt.Println("\nEncode struct to JSON:")
EncodeJSON(&user2)
}
结语
在本教程中,我们学习了如何读取JSON文件,使用marshal 和unmarshal 函数对数据进行编码和解码,以及使用标签定义结构。
我们的例子包括用于输入用户档案信息的简单字段,但你可以使用本教程的信息来构建一些复杂的应用程序。
我希望你喜欢这篇文章,并且学到了一些有用的东西!
The Posturing JSON for Goappeared first onLogRocket Blog.