为Go配置JSON

1,987 阅读5分钟

大多数现代应用程序需要在多个服务之间进行通信,而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文件,使用marshalunmarshal 函数对数据进行编码和解码,以及使用标签定义结构。

我们的例子包括用于输入用户档案信息的简单字段,但你可以使用本教程的信息来构建一些复杂的应用程序。

我希望你喜欢这篇文章,并且学到了一些有用的东西!

The Posturing JSON for Goappeared first onLogRocket Blog.