首页  >  文章  >  后端开发  >  golang对象转json

golang对象转json

WBOY
WBOY原创
2023-05-10 09:00:361107浏览

在golang中将一个对象转换成json是一件非常常见的事情,相信大部分golang开发者都会遇到。本篇文章就来分享一下在golang中如何将一个对象转换成json的方法和技巧。

  1. 使用encoding/json包

首先来看golang标准库中提供的encoding/json包。这个包提供了非常简单易用的函数和类型,可以让我们轻松地将一个对象转换成json格式的字符串或者将一个json格式的字符串转换成一个对象。

需要注意的是,对象必须是可导出的(即首字母大写),否则json包无法访问它的字段。

下面是使用encoding/json包将Student对象转换成json格式字符串的简单示例代码:

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    Name  string
    Age   int
    Score float64
}

func main() {
    s := Student{
        Name:  "Tom",
        Age:   18,
        Score: 90.5,
    }
    b, err := json.Marshal(s)
    if err != nil {
        fmt.Println("json.Marshal failed:", err)
        return
    }
    fmt.Println(string(b))
}

输出:

{"Name":"Tom","Age":18,"Score":90.5}

可以看到,json包提供的Marshal函数可以将一个结构体对象序列化成json格式的字符串。

对于一个复杂的对象,我们也可以很容易地把它序列化成json格式的字符串。比如下面这个由多个Student对象组成的数组:

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    Name  string
    Age   int
    Score float64
}

func main() {
    students := []Student{
        {Name: "Tom", Age: 18, Score: 90.5},
        {Name: "Jerry", Age: 19, Score: 96.5},
        {Name: "Alice", Age: 17, Score: 85.5},
    }
    b, err := json.Marshal(students)
    if err != nil {
        fmt.Println("json.Marshal failed:", err)
        return
    }
    fmt.Println(string(b))
}

输出:

[{"Name":"Tom","Age":18,"Score":90.5},{"Name":"Jerry","Age":19,"Score":96.5},{"Name":"Alice","Age":17,"Score":85.5}]

同样的,我们可以使用json包提供的Unmarshal函数将一个json格式的字符串解析成一个对象。例如:

package main

import (
    "encoding/json"
    "fmt"
)

type Point struct {
    X int `json:"x"`
    Y int `json:"y"`
}

type Line struct {
    Start Point `json:"start"`
    End   Point `json:"end"`
}

func main() {
    jsonStr := `
    {
        "start": {
            "x": 1,
            "y": 2
        },
        "end": {
            "x": 3,
            "y": 4
        }
    }`
    var line Line
    err := json.Unmarshal([]byte(jsonStr), &line)
    if err != nil {
        fmt.Println("json.Unmarshal failed:", err)
        return
    }
    fmt.Printf("%#v
", line)
}

输出:

main.Line{Start:main.Point{X:1, Y:2}, End:main.Point{X:3, Y:4}}

该示例代码中,我们定义了一个Line对象,它包含了两个Point对象。使用json包提供的Unmarshal函数将一个json格式的字符串解析成Line对象,然后进行输出。

  1. 通过结构体tag进行自定义json序列化和反序列化

如果我们想要自定义json格式的输出,比如修改某个字段的名字,该怎么办呢?这时候,golang中的struct tag就派上用场了。

在golang中,struct tag是一种对struct字段进行注释的方式,可以通过在字段的类型后添加字符串的方式实现。在使用json包序列化和反序列化时,我们可以使用struct tag来控制序列化和反序列化的过程。

下面是一个简单的示例代码,演示如何使用struct tag控制json序列化和反序列化的过程:

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Score float64
}

func main() {
    s := Student{
        Name:  "Tom",
        Age:   18,
        Score: 90.5,
    }
    fmt.Println("*** 序列化 ***")
    b, err := json.Marshal(s)
    if err != nil {
        fmt.Println("json.Marshal failed:", err)
        return
    }
    fmt.Println(string(b))

    fmt.Println("*** 反序列化 ***")
    jsonStr := `{"name":"Tom","age":18,"Score":90.5}`
    var student Student
    err = json.Unmarshal([]byte(jsonStr), &student)
    if err != nil {
        fmt.Println("json.Unmarshal failed:", err)
        return
    }
    fmt.Printf("%#v
", student)
}

输出:

*** 序列化 ***
{"name":"Tom","age":18,"Score":90.5}
*** 反序列化 ***
main.Student{Name:"Tom", Age:18, Score:90.5}

这里,我们将Student对象中的Name字段标注成"name",这样使用json.Marshal函数序列化时,就会将它的名字变成"name"。同样,使用json.Unmarshal函数反序列化时,也会自动识别"name"为Name字段。

通过struct tag的形式,我们还可以控制json输出中字段的可见性。例如:

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    Name  string `json:"name,omitempty"`
    Age   int    `json:"age"`
    Score float64
}

func main() {
    s := Student{
        Age:   18,
        Score: 90.5,
    }
    fmt.Println("*** 序列化 ***")
    b, err := json.Marshal(s)
    if err != nil {
        fmt.Println("json.Marshal failed:", err)
        return
    }
    fmt.Println(string(b))

    fmt.Println("*** 反序列化 ***")
    jsonStr := `{"name":"Tom","age":18,"Score":90.5}`
    var student Student
    err = json.Unmarshal([]byte(jsonStr), &student)
    if err != nil {
        fmt.Println("json.Unmarshal failed:", err)
        return
    }
    fmt.Printf("%#v
", student)
}

输出:

*** 序列化 ***
{"age":18,"Score":90.5}
*** 反序列化 ***
main.Student{Name:"Tom", Age:18, Score:90.5}

这里我们将Name字段标注成"omitempty",意思是如果Name字段的值是零值(即""),那么在json输出时就忽略这个字段。

  1. 使用第三方库

当我们需要进行更复杂的json序列化和反序列化时,golang标准库或许就有点力不足了。这时候,我们可以借助一些第三方库,来帮助我们实现更灵活的操作。

下面是一个使用第三方库进行json序列化和反序列化的示例代码,这个示例代码使用了json-iterator/go包,这个包是目前最快的golang json库之一。

package main

import (
    "fmt"
    "github.com/json-iterator/go"
)

type Student struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Score float64 `json:"score,omitempty"`
}

func main() {
    student := Student{
        Name:  "Tom",
        Age:   18,
        Score: 0,
    }
    fmt.Println("*** 序列化 ***")
    json := jsoniter.ConfigCompatibleWithStandardLibrary
    b, err := json.Marshal(student)
    if err != nil {
        fmt.Println("json.Marshal failed:", err)
        return
    }
    fmt.Println(string(b))

    fmt.Println("*** 反序列化 ***")
    jsonStr := `{"name":"Tom","age":18}`
    err = json.Unmarshal([]byte(jsonStr), &student)
    if err != nil {
        fmt.Println("json.Unmarshal failed:", err)
        return
    }
    fmt.Printf("%#v
", student)
}

输出:

*** 序列化 ***
{"name":"Tom","age":18}
*** 反序列化 ***
main.Student{Name:"Tom", Age:18, Score:0}

需要注意的是,使用第三方库虽然可以实现更灵活的json操作,但同时也可能会引入性能降低或代码复杂度增加等问题,需要根据具体场景进行选择。

本文介绍了几种golang中将对象转换成json的方法和技巧,希望本文能够对读者有所帮助。

以上是golang对象转json的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn