Go解析Json

一、Go解析Json數組

Json數組是一組有序的值序列,使用方括弧[]來表示。在Go語言中,如果想要解析Json數組,只需要使用json.Unmarshal()即可。

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    var persons []Person

    jsonStr := `[{"Name": "Alice","Age": 20},{"Name": "Bob","Age":22}]`

    if err := json.Unmarshal([]byte(jsonStr), &persons); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(persons)
}

在上述代碼中,首先定義了一個Person結構體,包括Name和Age兩個欄位。接著定義了一個persons切片,用於存儲解析後的Json數組。然後,使用json.Unmarshal()方法將Json字元串解析為persons切片,如果解析失敗,輸出錯誤信息。最後,列印解析後的persons切片。

需要注意的是,Go語言的json.Unmarshal()方法需要傳入Json字元串的位元組切片以及目標數據結構的指針。

二、Go解析Json對象數組

Json對象數組是一組由鍵值對組成的Json對象序列,使用花括弧{}來表示。在Go語言中,如果想要解析Json對象數組,同樣可以使用json.Unmarshal()方法。

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    var persons map[string]Person

    jsonStr := `{
        "Alice": {"Name": "Alice","Age": 20},
        "Bob":   {"Name": "Bob","Age":22}
    }`

    if err := json.Unmarshal([]byte(jsonStr), &persons); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(persons)
}

在上述代碼中,定義了一個Person結構體和一個persons映射,用於存儲解析後的Json對象數組。使用json.Unmarshal()方法將Json字元串解析為persons映射類型。如果解析失敗,輸出錯誤信息。最後,列印解析後的persons映射。

三、Go解析Json失敗

在Go語言中,如果Json字元串格式不正確,使用json.Unmarshal()方法會返回解析錯誤。例如:

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    var persons []Person

    jsonStr := `{"Name": "Alice","Age": 20},{"Name": "Bob","Age":22}}`

    if err := json.Unmarshal([]byte(jsonStr), &persons); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(persons)
}

在上述代碼中,Json字元串中的花括弧不匹配,導致json.Unmarshal()方法拋出錯誤。

四、Go解析Json的方法

在Go語言中,解析Json字元串有多種方式。除了在前三個小標題中提到的json.Unmarshal()方法外,還有json.Decoder和json.Encoder方法。

1、json.Decoder方法

json.Decoder方法是一種基於流的Json解析方式,主要用於逐個Json值讀取,適用於大型Json文件解析。

package main

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

type Person struct {
    Name string
    Age  int
}

func main() {
    var persons []Person

    jsonStr := `[{"Name": "Alice","Age": 20},{"Name": "Bob","Age":22}]`
    
    decoder := json.NewDecoder(strings.NewReader(jsonStr))

    _, err := decoder.Token()
    if err != nil {
        fmt.Println(err)
    }

    for decoder.More() {
        var person Person
        if err := decoder.Decode(&person); err != nil {
            fmt.Println(err)
            return
        }
        persons = append(persons, person)
    }

    fmt.Println(persons)
}

在上述代碼中,首先定義了一個Person結構體和一個persons切片,用於存儲解析後的Json數組。然後,使用strings.NewReader()方法創建一個Reader對象,創建json.Decoder對象,從中讀取Token。接著,使用decoder.More()方法判斷是否有下一個Json值。如果有,使用decoder.Decode()方法解析Json值為Person結構體。然後,將解析後的Person結構體添加到persons切片中。

2、json.Encoder方法

json.Encoder方法是一種基於流的Json編碼方式,主要用於逐個Json值寫入到一個流中,適用於處理大型Json文件。

package main

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

type Person struct {
    Name string
    Age  int
}

func main() {
    persons := []Person{{"Alice", 20}, {"Bob", 22}}

    file, err := os.Create("example.json")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()

    encoder := json.NewEncoder(file)

    if err := encoder.Encode(persons); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("Json file created successfully")
}

在上述代碼中,首先定義了一個persons切片,將解析後的Person結構體添加到此切片中。然後,使用os.Create()方法創建一個json文件,並創建json.Encoder對象,從中寫入persons數據到文件中。

五、Go解析Json的性能

對於Json解析的性能問題,需要注意以下三點:

1、盡量不要使用json.Unmarshal()和json.Marshal()方法在高性能的應用程序中。

2、使用json.Decoder和json.Encoder方法的效率要高於Unmarshal和Marshal方法。如果要在高性能應用程序中進行Json解析,請考慮使用Decoder方法。

3、Json字元串解析耗費時間,因此,應盡量使用Json流解析。例如:使用json.Decoder方法的More()函數和Decoder()方法。

六、Go解析Json單引號

Go語言的json包默認只能解析雙引號標記的Json字元串。如果要解析單引號標記的Json字元串,則需要進行一定的處理。可以使用替換函數,將Json字元串中的單引號轉換為雙引號,然後再進行解析。

package main

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

type Person struct {
    Name string
    Age  int
}

func main() {
    var persons []Person
    
    jsonStr := `[
        {'Name': 'Alice','Age': 20},
        {'Name': 'Bob','Age':22}
    ]`

    jsonStr = strings.Replace(jsonStr, "'", "\"", -1)

    if err := json.Unmarshal([]byte(jsonStr), &persons); err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(persons)
}

在上述代碼中,首先定義了一個Person結構體和一個persons切片,將解析後的Person結構體添加到persons切片中。然後,定義一個Json字元串,使用strings.Replace()函數,將Json字元串中的單引號替換成雙引號。最後,使用json.Unmarshal()方法解析Json字元串。

七、Go解析Json字元串

在Go語言中,Json字元串解析需要使用json.Unmarshal()方法。需要注意的是,json.Unmarshal()方法只能解析成為基本數據類型或Struct結構體。如果要解析Json字元串中的嵌套Json,需要將其解析為位元組切片,再次使用json.Unmarshal()方法進行解析。

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    var jsonString = `
        {
            "Name": "Alice",
            "Age": 20,
            "array": [1, 2, 3],
            "nested": {
                "Key": "value"
            }
        }
    `
    var person Person

    if err := json.Unmarshal([]byte(jsonString), &person); err != nil {
        fmt.Println("Json parsing error: ", err)
        return
    }

    fmt.Println("Name: ", person.Name)
    fmt.Println("Age: ", person.Age)
    fmt.Println("Array: ", person.Array)
    fmt.Println("Nested: ", person.Nested.Key)
}

在上述代碼中,首先定義一個Json字元串,包括Name、Age、array和nested屬性。然後定義一個Person結構體。使用json.Unmarshal()方法解析jsonString為Person結構體。最後,列印解析後的Person結構體。

八、Go解析Json的幾種方式

除了在本文中介紹的Json解析方式,Go語言中還有其他多種Json解析方式,如下:

1、使用gojson方法解析Json字元串

GoJson方法是一種快速、簡單的Json解析方式。它使用Go的struct將Json定義為強類型,同時能夠在編譯時生成解析代碼,因此運行速度更快。

package main

import (
    "fmt"
    "github.com/ChimeraCoder/gojson"
)

func main() {
    jsonStr := `{"Name": "Alice","Age": 20}`
    obj, err := UnmarshalPerson([]byte(jsonStr))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(obj)
}

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

func UnmarshalPerson(data []byte) (Person, error) {
    var r Person
    err := gojson.Unmarshal(data, &r)
    return r, err
}

在上述代碼中,使用gojson將Person解析為強類型。首先定義一個Person結構體,使用json標記每個欄位,以將Json屬性映射到相應的struct欄位。接著,定義UnmarshalPerson函數,使用gojson.Unmarshal()方法解析Json數據。

2、手動解析Json字元串

手動解析Json字元串是一種較為底層的Json解析方式。它基於Go語言的標準庫,在解析Json字元串時,可以更精準地控制編碼和解碼過程,並可以支持更高效的解析方式。

package main

import (
    "bytes"
    "fmt"
)

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

func Decode(data []byte) (*Person, error) {
    var p Person
    decoder := NewDecoder(bytes.NewBuffer(data))
    for decoder.More() {
        key, err := decoder.Token()
        if err != nil {
            return nil, err
        }
        switch key {
        case "Name":
            decoder.Decode(&p.Name)
        case "Age":
            decoder.Decode(&p.Age)
        default:
            continue
        }
    }
    return &p, nil
}

func main() {
    jsonStr := `{"Name": "Alice","Age": 20}`
    obj, err := Decode([]byte(jsonStr))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(obj)
}

在上述代碼中,手動解析Json字元串需要使用Token和Decode方法,並通過for循環遍歷每個token。在Decode方法中,首先定義一個Person結構體。然後,創建一個decoder對象,使用decoder.More()方法判斷是否有下一個Json值。使用decoder.Token()方法獲取Json Key,然後使用switch語句解析相應的值。最後返回Person結構體。

九、Go解析Json麻煩

Go解析Json在某些情況下可能會比較麻煩。例如,在解析Json字元串中的空欄位時,可能會遇到一些困難。

package main

import (
"encoding/json"
"fmt"
)

type Person struct {
Name

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/151590.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-11 13:43
下一篇 2024-11-11 13:43

相關推薦

  • 運維Python和GO應用實踐指南

    本文將從多個角度詳細闡述運維Python和GO的實際應用,包括監控、管理、自動化、部署、持續集成等方面。 一、監控 運維中的監控是保證系統穩定性的重要手段。Python和GO都有強…

    編程 2025-04-29
  • go-chassis

    本文將深入探究go-chassis,包括它的基本概念,特性,以及如何使用它構建微服務應用程序。 一、微服務架構及其優勢 微服務架構是一種將應用程序拆分為小型、自治服務的體系結構。每…

    編程 2025-04-29
  • JSON的MD5

    在Web開發過程中,JSON(JavaScript Object Notation)是最常用的數據格式之一。MD5(Message-Digest Algorithm 5)是一種常用…

    編程 2025-04-29
  • 使用Java將JSON寫入HDFS

    本篇文章將從以下幾個方面詳細闡述Java將JSON寫入HDFS的方法: 一、HDFS簡介 首先,先來了解一下Hadoop分散式文件系統(HDFS)。HDFS是一個可擴展性高的分散式…

    編程 2025-04-29
  • 使用Go-Redis獲取Redis集群內存使用率

    本文旨在介紹如何使用Go-Redis獲取Redis集群的內存使用率。 一、Go-Redis簡介 Go-Redis是一個用於連接Redis伺服器的Golang客戶端。它支持Redis…

    編程 2025-04-28
  • Kong 使用第三方的go插件

    本文將針對Kong使用第三方的go插件進行詳細闡述。首先,我們解答下標題的問題:如何使用第三方的go插件?我們可以通過編寫插件來達到此目的。 一、插件架構介紹 Kong的插件系統采…

    編程 2025-04-28
  • Go中struct的初始化

    本文將從多個方面詳細闡述Go中struct的初始化方式,包括使用字面量初始化、使用new函數初始化以及使用構造函數等。通過本文的介紹,讀者能夠更深入的了解Go中struct的初始化…

    編程 2025-04-28
  • 如何使用Newtonsoft datatable轉Json

    Newtonsoft DataTable 是一個基於.NET的JSON框架,也是一個用於序列化和反序列化JSON的強大工具。 在本文中,我們將學習如何使用Newtonsoft Da…

    編程 2025-04-28
  • JPRC – 輕鬆創建可讀性強的 JSON API

    本文將介紹一個全新的 JSON API 框架 JPRC,通過該框架,您可以輕鬆創建可讀性強的 JSON API,提高您的項目開發效率和代碼可維護性。接下來將從以下幾個方面對 JPR…

    編程 2025-04-27
  • Go源碼閱讀

    Go語言是Google推出的一門靜態類型、編譯型、並髮型、語法簡單的編程語言。它因具有簡潔高效,內置GC等優秀特性,被越來越多的開發者所鍾愛。在這篇文章中,我們將介紹如何從多個方面…

    編程 2025-04-27

發表回復

登錄後才能評論