Go 处理 JSON 教程 - 如何创建和解析 JSON 数据

栏目: Go · 发布时间: 5年前

内容简介:本文介绍在使用 Go 标准库中的

本文介绍在 Go 语言中,如何创建和解析 JSON 数据。

Go 处理 JSON 教程 - 如何创建和解析 JSON 数据

一、创建 JSON

使用 Go 标准库中的 encoding/json ,可以很方便从 struct、map、slice 等数据结构体来创建 JSON 数据。

1、从 struct 创建

通过 json.Marshal ,可以很方便的将一个 struct 转化为 []byte 类型的 JSON 数据。

package main

import (  
    "encoding/json"
    "fmt"
)

type Person struct {  
    Name   string
    Age    int
    Emails []string
}

func main() {  
    bingo := Person{
        Name:   "Bingo Huang",
        Age:    30,
        Emails: []string{"go@bingohuang.com", "me@bingohuang.com"},
    }
    json_bytes, err := json.Marshal(bingo)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%s",json_bytes)
}

输出:

{"Name":"Bingo Huang","Age":30,"Emails":[go@bingohuang.com", "me@bingohuang.com"]}

注意: 1. 结构体中的字段名,需要大写开头,否则不会被输出

2. 结构体中可以嵌入其他结构体

3. json.Marshal 函数返回一个 []byte 类型的 JSON 数据和一个 error ,别忘了处理该 error

4. 返回的 []byte 类型 JSON 数据,如果你想当成字符串处理,需要做强制转换: string(json_bytes)

2、定义字段名称

如果你希望输出的 JSON 字段,不一定要大写字母开头,甚至想自定义 JSON 字段名,可以打上 json tag

type Person struct {  
    Name   string   `json:"name"`
    Age    int      `json:"age"`
    Emails []string `json:"emails"`
}

再次输出:

{"name":"Bingo Huang","age":30,"emails":["go@bingohuang.com","me@bingohuang.com"]}

3、忽略空字段

如果你希望某些字段在数据为空时能能被自动忽略,只需加上 omitempty 标签。

package main

import (  
    "encoding/json"
    "fmt"
)

type Person struct {  
    Name   string      `json:"name,omitempty"`
    Age    int         `json:"age,omitempty"`
    Emails []string    `json:"emails,omitempty"`
}

func main() {  
    bingo := Person{
        Name: "Bingo Huang",
    }
    json_bytes, _ := json.Marshal(bingo)
    fmt.Printf("%s", json_bytes)
}

输出:

{"name":"Bingo Huang"}

4、跳过某字段

如果你不想让某个字段(无论该字段数据是否为空)输出到 JSON 中,可使用 - 来跳过。

package main

import (  
    "encoding/json"
    "fmt"
)

type Person struct {  
    Name   string      `json:"name,omitempty"`
    Age    int         `json:"-"`
    Emails []string    `json:"emails,omitempty"`
}

func main() {  
    bingo := Person{
        Name: "Bingo Huang",
        Age:  27,
    }
    json_bytes, _ := json.Marshal(bingo)
    fmt.Printf("%s", json_bytes)
}

输出:

{"name":"Bingo Huang"}

5、从 map 和 slice 创建

mapslice 来创建 JSON,也很容易,直接上示例

package main

import (  
    "encoding/json"
    "fmt"
)

func main() {  
    bingo := map[string]interface{}{
        "name": "Bingo Huang",
        "age":  30,
    }
    json_bytes, _ := json.Marshal(bingo)
    fmt.Printf("%s", json_bytes)
}

输出:

{"age":30,"name":"Bingo Huang"}
package main

import (  
    "encoding/json"
    "fmt"
)

func main() {  
    emails := []string{"go@bingohuang.com", "me@bingohuang.com"}
    json_bytes, _ := json.Marshal(emails)
}

输出:

["go@bingohuang.com","me@bingohuang.com"]

二、解析 JSON

创建 JSON 是如此方便,那反过来看看 GO 如何解析 JSON。

1、解析到 struct

相反,可以通过 json.Unmarshal 来将一个 []byte 类型的 JSON 数据解析到 struct 中。

package main

import (  
    "encoding/json"
    "fmt"
)

type Person struct {  
    Name   string   `json:"name"`
    Age    int      `json:"age"`
    Emails []string `json:"emails"`
}

func main() {  
    json_bytes := []byte(`
        {
            "Name":"Bingo Huang",
            "Age":30,
            "Emails":["go@bingohuang.com","me@bingohuang.com"]
        }
    `)
    bingo := Person{}
    err := json.Unmarshal(json_bytes, &bingo)
    if err != nil {
        panic(err)
    }
    fmt.Println(bingo.Name, bingo.Age, bingo.Emails)
}

这里我们将 json_bytes 和 Person 的指针传递给 json.Unmarshal ,注意要传递结构体的 指针 ,因为解析器需要给结构体写入数据。

如果 JSON 数据中不包含结构体的某些字段,转换成 struct 时字段会被忽略,反过来如果结构体中某些字段不需要输出 JSON,也会被忽略,如下:

package main

import (  
    "encoding/json"
    "fmt"
)

type Person struct {  
    Name    string   `json:"name"`
    Age     int      `json:"age"`
    Emails  []string `json:"emails"`
    Address string
}

func main() {  
    json_bytes := []byte(`
        {
            "Name":"Bingo Huang",
            "Age":30
        }
    `)
    var bingo Person
    err := json.Unmarshal(json_bytes, &bingo)
    if err != nil {
        panic(err)
    }
    fmt.Println(bingo.Emails)
    fmt.Println(bingo.Address)
}

这里 EmailsAddress 字段都被忽略了,输出都为空。

2、解析到 map 和 slice

通过 json.Unmarshal 将 JSON 数据解析到 mapslice 也十分方便,这里以 map 为例。

package main

import (  
    "encoding/json"
    "fmt"
)

func main() {  
    json_bytes := []byte(`
        {
            "Name":"Bingo Huang",
            "Age":30,
            "Emails":["go@bingohuang.com","me@bingohuang.com"]
        }
    `)
    var bingo map[string]interface{}
    err := json.Unmarshal(json_bytes, &bingo)
    if err != nil {
        panic(err)
    }
    fmt.Println(bingo["Name"], bingo["Age"], bingo["Emails"], bingo["Score"])
}

三、JSON 流处理

json 包还提供了另外两个函数 NewEncoderNewDecoder ,提供 EncoderDecoder 类型,可支持 io.Readerio.Writer 接口做流处理。

1、创建 JSON 到文件中

我们可以将一个 JSON 文件转化到结构体中。

package main

import (  
    "encoding/json"
    "fmt"
    "os"
)

func main() {  
    fileReader, _ := os.Open("bingo.json")
    var bingo map[string]interface{}
    json.NewDecoder(fileReader).Decode(&bingo)
    fmt.Println(bingo)
}

bingo.json 内容如下:

{
  "Name":"Bingo Huang",
  "Age":30,
  "Emails":["go@bingohuang.com","me@bingohuang.com"]
}

输出:

map[Name:Bingo Huang Age:30 Emails:[go@bingohuang.com me@bingohuang.com]]

2、从文件中解析 JSON

同样,可以反过来,将对象转化为 JSON 格式,并写入文件中。

package main

import (  
    "encoding/json"
    "os"
)

type Person struct {  
    Name   string
    Age    int
    Emails []string
}

func main() {  
    bingo := Person{
        Name:   "Bingo Huang",
        Age:    30,
        Emails: []string{"go@bingohuang.com","me@bingohuang.com"},
    }
    fileWriter, _ := os.Create("output.json")
    json.NewEncoder(fileWriter).Encode(bingo)
}

输出的 out.json 文件为:

{"Name":"Bingo Huang","Age":30,"Emails":["go@bingohuang.com","me@bingohuang.com"]}

参考资料

  1. Golang: Working with JSON
  2. encoding/json

以上所述就是小编给大家介绍的《Go 处理 JSON 教程 - 如何创建和解析 JSON 数据》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

设计模式之禅

设计模式之禅

秦小波 / 机械工业出版社 / 2010年3月 / 69.00元

如果说“四人帮”的《设计模式》是设计模式领域的“圣经”,那么之后出版的各种关于设计模式的书都可称之为“圣经”的“注释版”或“圣经的故事”。本书是得道者对“圣经”的“禅悟”,它既不像“圣经”那样因为惜字如金、字字珠玑而深奥、晦涩和难懂,又比“圣经”的“注释版”更深刻和全面、更通俗和生动、更接近开发者遇到的实践场景,更具指导性。本书兼收并蓄、博采众长,也许是设计模式领域里的下一个里程碑之作。 全......一起来看看 《设计模式之禅》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具