您的位置:

golangjson:从多个角度深入了解golang中的JSON

一、golangjson库

在golang中,操作JSON数据是件非常常见的事情。golang内置了encoding/json库,用于JSON数据的编码和解码。通过encoding/json库,可以方便地将go中的数据结构序列化为JSON字符串或者反之。

例如,下面的代码演示了如何将一个结构体转换成JSON字符串:

type User struct {
    Name  string `json:"username"`
    Age   int    `json:"userage"`
    Email string `json:"email"`
}

func main() {
    user1 := User{Name: "小明", Age: 18, Email: "xiaoming@example.com"}

    jsonBytes, err := json.Marshal(user1)
    if err != nil {
        // handle the error
    }

    jsonString := string(jsonBytes)
    fmt.Println(jsonString)
}

输出结果为:

{"username":"小明","userage":18,"email":"xiaoming@example.com"}

除了将一个数据结构转换成JSON字符串,encoding/json库还提供了将JSON字符串转化为go数据结构的功能。下面的代码演示了如何将一个JSON字符串解码成go中的一个数据结构:

type User struct {
    Name  string `json:"username"`
    Age   int    `json:"userage"`
    Email string `json:"email"`
}

func main() {
    jsonStr := `{"username":"小明","userage":18,"email":"xiaoming@example.com"}`

    var user1 User
    err := json.Unmarshal([]byte(jsonStr), &user1)
    if err != nil {
        // handle the error
    }

    fmt.Println(user1)
}

输出结果为:

{小明 18 xiaoming@example.com}

二、golang jsonpath

在golang中,使用jsonpath可以更方便地从JSON数据中提取所需的部分信息。golang中使用simeji/jp库实现jsonpath查询。

例如,下面的代码演示了如何使用jsonpath查询JSON数据中的名称为“Bob”的用户的email:

jsonStr := `{
    "users": [
        {
            "name": "Alice",
            "email": "alice@example.com"
        },
        {
            "name": "Bob",
            "email": "bob@example.com"
        }
    ]
}`

jpath := "$.users[?(@.name == 'Bob')].email"

var data interface{}
json.Unmarshal([]byte(jsonStr), &data)

result, _ := jp.Query(data, jpath)

fmt.Println(result[0].(string))

输出结果为:

bob@example.com

三、golang json转map

有时候,我们需要将一个JSON字符串转换成map类型的数据结构,方便进行操作。golang中,使用encoding/json库可以方便地将JSON字符串转换成map类型数据结构。

例如,下面的代码演示了如何将一个JSON字符串转换成map类型的数据结构:

jsonStr := `{"name":"小明","age":18,"emails":["xiaoming@example.com","ming@example.com"]}`

var dataMap map[string]interface{}
json.Unmarshal([]byte(jsonStr), &dataMap)

fmt.Println(dataMap["name"])              // "小明"
fmt.Println(dataMap["age"])               // 18
fmt.Println(dataMap["emails"].([]interface{})[0]) // "xiaoming@example.com"
fmt.Println(dataMap["emails"].([]interface{})[1]) // "ming@example.com"

四、golang json转结构体

有时候,我们需要将一个JSON字符串转换成结构体类型的数据结构,方便进行操作。golang中,使用encoding/json库可以方便地将JSON字符串转换成结构体类型数据结构。

例如,下面的代码演示了如何将一个JSON字符串转换成结构体类型的数据结构:

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

func main() {
    jsonStr := `{"name":"小明","age":18,"emails":["xiaoming@example.com","ming@example.com"]}`

    var person Person
    json.Unmarshal([]byte(jsonStr), &person)

    fmt.Println(person.Name)              // "小明"
    fmt.Println(person.Age)               // 18
    fmt.Println(person.Emails[0])         // "xiaoming@example.com"
    fmt.Println(person.Emails[1])         // "ming@example.com"
}

五、golang json tag

在golang中,可以使用tag的方式来控制JSON数据序列化和反序列化的方式。例如,下面的代码演示了如何使用tag来定制json字符串的key:

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

func main() {
    person1 := Person{Name: "小明", Age: 18, Emails: []string{"xiaoming@example.com", "ming@example.com"}}

    jsonBytes, err := json.Marshal(person1)
    if err != nil {
        // handle the error
    }

    jsonString := string(jsonBytes)
    fmt.Println(jsonString)
}

输出结果为:

{"name":"小明","age":18,"emails":["xiaoming@example.com","ming@example.com"]}

我们可以看到,在Person结构体的Emails字段上,使用了omitempty tag,表示如果Emails字段为空,则不会被序列化成JSON字符串中的key。

六、golang json map

在golang中,可以使用map[string]interface{}类型来表示JSON对象类型的数据结构。例如下面的代码演示了如何创建一个map[string]interface{}类型的JSON对象:

dataMap := map[string]interface{}{
    "name":   "小明",
    "age":    18,
    "emails": []string{"xiaoming@example.com", "ming@example.com"},
}

jsonBytes, err := json.Marshal(dataMap)
if err != nil {
    // handle the error
}

jsonString := string(jsonBytes)
fmt.Println(jsonString)

输出结果为:

{"age":18,"emails":["xiaoming@example.com","ming@example.com"],"name":"小明"}

七、golang json解析

在golang中,只要满足JSON格式的数据都可以使用encoding/json库进行解析。例如,下面的代码演示了如何解析JSON格式的文本文件:

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

func main() {
    file, err := os.Open("person.json")
    if err != nil {
        // handle the error
    }
    defer file.Close()

    var person Person
    decoder := json.NewDecoder(file)
    err = decoder.Decode(&person)
    if err != nil {
        // handle the error
    }

    fmt.Println(person)
}

八、golang jsoniter

jsoniter是golang的一个高性能JSON库,可以比encoding/json库更快地进行JSON数据的编码和解码。

例如,下面的代码演示了如何使用jsoniter库进行JSON数据的解码:

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

func main() {
    jsonStr := `{"name":"小明","age":18,"emails":["xiaoming@example.com","ming@example.com"]}`

    var person Person
    jsoniter.Unmarshal([]byte(jsonStr), &person)

    fmt.Println(person)
}

九、golang json解析太蠢

有时候,我们在使用golang自带的encoding/json库进行编码和解码的时候,会遇到一些很蠢的问题,例如有些结构体字段名和JSON字符串中的key名称不一样,就会导致编码和解码失败。

例如,下面的代码演示了编码和解码失败的情况:

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

func main() {
    jsonStr := `{"username":"小明","userage":18,"email":"xiaoming@example.com"}`

    var person Person
    json.Unmarshal([]byte(jsonStr), &person)

    fmt.Println(person)
}

报错信息为:

json: unknown field "username" [recovered]

解决这个问题的方法之一是,在结构体中使用tag来指定JSON字符串中对应的key名称。

十、golang json unmarshal

golang中,使用encoding/json库可以方便地将JSON字符串转换为go数据结构。encoding/json库提供了两个函数:json.Marshal()和json.Unmarshal()。前者用于将go数据结构序列化为JSON字符串,后者用于将JSON字符串反序列化为go数据结构。

例如,下面的代码演示了使用json.Unmarshal()函数将JSON字符串解析为go数据结构:

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    jsonStr := `{"name":"小明","age":18}`

    var person Person
    json.Unmarshal([]byte(jsonStr), &person)

    fmt.Println(person.Name) // "小明"
    fmt.Println(person.Age)  // 18
}
以上就是golang中JSON处理的一些方面的介绍,包括golang中自带的encoding/json库、jsonpath等内容,以及使用tag来控制JSON序列化和反序列化的方式,使用map[string]interface{}表示JSON数据等内容。同时,也值得注意的是,在使用golang自带的encoding/json库进行编码和解码的时候,需要注意一些坑点,例如结构体字段名与JSON中的key名不一样会导致编码或者解码失败。