最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Go中使用JSON(附demo)

 更新時(shí)間:2022年02月25日 10:49:54   作者:迪魯賓  
Go開(kāi)發(fā)人員經(jīng)常需要處理JSON內(nèi)容,本文主要介紹了在Go中使用JSON,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Golang(又稱Go)是一種靜態(tài)類型的編譯編程語(yǔ)言,具有類似C語(yǔ)言的語(yǔ)法。Go為通用編程提供了一個(gè)最小的語(yǔ)法,只有25個(gè)關(guān)鍵詞。

現(xiàn)在,程序員使用Go來(lái)構(gòu)建開(kāi)發(fā)者工具、云計(jì)算工具、CLI程序以及桌面和網(wǎng)絡(luò)應(yīng)用。Go在構(gòu)建高性能軟件系統(tǒng)方面非常受歡迎,在這些系統(tǒng)中,并發(fā)性起著關(guān)鍵作用。

Go開(kāi)發(fā)人員經(jīng)常需要處理JSON內(nèi)容。例如,我們經(jīng)常要讀取JSON文件來(lái)填充Go對(duì)象,并從現(xiàn)有的Go對(duì)象中寫入JSON文件。像其他現(xiàn)代編程語(yǔ)言一樣,Go提供了一個(gè)標(biāo)準(zhǔn)庫(kù)模塊來(lái)處理JSON結(jié)構(gòu)。

在本教程中,我將通過(guò)實(shí)際例子解釋如何在Go中處理JSON。此外,我還將解釋一些高級(jí)概念,如自定義JSON編碼和解碼。

Go編碼/json包

Go提供了encoding/json包,通過(guò)標(biāo)準(zhǔn)庫(kù)的編碼命名空間處理JSON內(nèi)容。encoding/json包提供了API函數(shù),用于從Go對(duì)象生成JSON文檔--以及從JSON文檔中填充Go對(duì)象。此外,它還允許你定制JSON到Go和Go到JSON的翻譯過(guò)程。

JSON規(guī)范同時(shí)支持格式化和內(nèi)聯(lián)(minified)文檔。因此,Go encoding/json包可以讓開(kāi)發(fā)者同時(shí)生成格式化和最小化的JSON文檔。

編碼。將 Go 對(duì)象轉(zhuǎn)換為 JSON

什么是Go中的marshaling?

將Go對(duì)象編碼為JSON格式被稱為marshaling。我們可以使用Marshal 函數(shù)來(lái)將 Go 對(duì)象轉(zhuǎn)換為 JSON。Marshal 函數(shù)的語(yǔ)法如下。

func Marshal(v interface{}) ([]byte, error)

它接受一個(gè)空接口。換句話說(shuō),你可以向該函數(shù)提供任何Go數(shù)據(jù)類型--整數(shù)、浮點(diǎn)、字符串、結(jié)構(gòu)體、地圖等--因?yàn)樗蠫o數(shù)據(jù)類型定義都可以用空接口表示。它返回兩個(gè)值:一個(gè)編碼JSON的字節(jié)片和error

裝載簡(jiǎn)單對(duì)象

如上所述,我們可以用原始的Go數(shù)據(jù)類型生成JSON。例如,你可以將Go字符串轉(zhuǎn)換為JSON字符串。

但由于轉(zhuǎn)換基元在現(xiàn)實(shí)世界的軟件開(kāi)發(fā)項(xiàng)目中沒(méi)有幫助,讓我們從轉(zhuǎn)換一些簡(jiǎn)單對(duì)象開(kāi)始。下面的代碼片斷將從一個(gè)map數(shù)據(jù)結(jié)構(gòu)中編碼JSON。

package main
import (
    "fmt"
    "encoding/json"
)
func main() {
    fileCount := map[string]int{
        "cpp": 10,
        "js": 8,
        "go": 10,
    }
    bytes, _ := json.Marshal(fileCount)
    fmt.Println(string(bytes))
}

這里我們使用string() ,將字節(jié)轉(zhuǎn)換為字符串。Go將map數(shù)據(jù)結(jié)構(gòu)編碼為JSON鍵值對(duì)象。一旦你運(yùn)行上述代碼,你將得到如下所示的輸出。

你也可以從一個(gè)結(jié)構(gòu)中對(duì)JSON進(jìn)行編碼,如下面的示例代碼所示。

package main
import (
    "fmt"
    "encoding/json"
)
type Book struct {
    Title string
    Author string
    Year int
}
func main() {
    myBook := Book{"Hello Golang", "John Mike", 2021}
    bytes, _ := json.Marshal(myBook)
    fmt.Println(string(bytes))
}

在這里,我們必須以大寫的英文字母開(kāi)始結(jié)構(gòu)字段名,以使這些字段可以導(dǎo)出到其他軟件包。如果你的結(jié)構(gòu)包含一個(gè)以小寫字母開(kāi)頭的字段,那么編碼/json包在編碼過(guò)程中不會(huì)包含這個(gè)特定的字段,也不會(huì)出現(xiàn)任何錯(cuò)誤。

上述代碼將輸出以下JSON結(jié)構(gòu)。

{"Title":"Hello Golang","Author":"John Mike","Year":2021}

對(duì)復(fù)雜對(duì)象進(jìn)行編碼

在前面的例子中,我們從Go對(duì)象中編碼了JSON,比如簡(jiǎn)單的map和structs。如果你試圖對(duì)整數(shù)數(shù)組、字符串?dāng)?shù)組和原始變量進(jìn)行編碼,Go將為這些元素產(chǎn)生簡(jiǎn)單的JSON結(jié)構(gòu)。

但大多數(shù)時(shí)候,我們必須從Go程序中的復(fù)雜對(duì)象中生成JSON文件,如產(chǎn)品列表、產(chǎn)品詳情和各種嵌套數(shù)據(jù)記錄。

首先,讓我們從一個(gè)產(chǎn)品列表中對(duì)JSON進(jìn)行編碼。請(qǐng)看下面的示例代碼。

package main
import (
    "fmt"
    "encoding/json"
)
type Seller struct {
    Id int
    Name string
    CountryCode string
}
type Product struct {
    Id int
    Name string
    Seller Seller
    Price int
}
func main() {
    products := []Product{
        Product {
            Id: 50,
            Name: "Writing Book",
            Seller: Seller {1, "ABC Company", "US"},
            Price: 100,
        },
        Product {
            Id: 51,
            Name: "Kettle",
            Seller: Seller {20, "John Store", "DE"},
            Price: 500,
        },
    }
    bytes, _ := json.Marshal(products)
    fmt.Println(string(bytes))
}

上面的代碼初始化了一個(gè)有兩個(gè)項(xiàng)目的產(chǎn)品列表。Product 結(jié)構(gòu)有一個(gè)Seller 結(jié)構(gòu)作為嵌套對(duì)象--所有的產(chǎn)品都放在一個(gè)產(chǎn)品片中。接下來(lái),我們將最終的產(chǎn)品列表發(fā)送到Marshal 函數(shù),將其編碼為JSON結(jié)構(gòu)。

一旦你運(yùn)行上述代碼片斷,你將得到以下輸出。

[{"Id":50,"Name":"Writing Book","Seller":{"Id":1,"Name":"ABC Company","CountryCode":"US"},"Price":100},{"Id":51,"Name":"Kettle","Seller":{"Id":20,"Name":"John Store","CountryCode":"DE"},"Price":500}]

正如你所看到的,Go可以從任何復(fù)雜的Go數(shù)據(jù)結(jié)構(gòu)中編碼JSON。但是現(xiàn)在,當(dāng)我們看上面的輸出時(shí),我們有兩個(gè)問(wèn)題。

  • 輸出的JSON結(jié)構(gòu)的鍵總是以大寫的英文字母開(kāi)始--我們?cè)鯓硬拍苤孛鸍SON字段?
  • 當(dāng)我們對(duì)大型復(fù)雜的結(jié)構(gòu)進(jìn)行編碼時(shí),輸出結(jié)果變得簡(jiǎn)直無(wú)法閱讀--我們?nèi)绾尾拍苊阑疛SON的輸出?

Go encoding/json軟件包通過(guò)額外的庫(kù)功能回答了上述問(wèn)題。

集合功能

Go提供了幾個(gè)功能,通過(guò)額外的API函數(shù)和結(jié)構(gòu)標(biāo)簽改善和定制JSON輸出。

重命名字段

你必須以大寫英文字母開(kāi)始結(jié)構(gòu)字段的聲明,以便讓JSON包訪問(wèn)它們。因此,你將永遠(yuǎn)得到大寫的英文字母作為JSON鍵。Go編碼/json包允許開(kāi)發(fā)人員通過(guò)JSON結(jié)構(gòu)標(biāo)簽隨意重命名JSON字段。

下面的代碼片斷對(duì)產(chǎn)品對(duì)象的JSON進(jìn)行編碼,并使用蛇形大小寫的JSON鍵。

package main
import (
    "fmt"
    "encoding/json"
)
type Seller struct {
    Id int `json:"id"`
    Name string `json:"name"`
    CountryCode string `json:"country_code"`
}
type Product struct {
    Id int `json:"id"`
    Name string `json:"name"`
    Seller Seller `json:"seller"`
    Price int `json:"price"`
}
func main() {
    book := Product{
        Id: 50,
        Name: "Writing Book",
        Seller: Seller {1, "ABC Company", "US"},
        Price: 100,
    }
    bytes, _ := json.Marshal(book)
    fmt.Println(string(bytes))
}

正如你所看到的,上面的代碼使用結(jié)構(gòu)標(biāo)簽來(lái)重命名每個(gè)導(dǎo)出的字段。結(jié)構(gòu)標(biāo)簽不是JSON編碼過(guò)程中的必選元素--它是一個(gè)可選的元素,在JSON編碼過(guò)程中重命名一個(gè)特定的結(jié)構(gòu)字段。

一旦你執(zhí)行上述代碼,你將得到以下輸出。

{"id":50,"name":"Writing Book","seller":{"id":1,"name":"ABC Company","country_code":"US"},"price":100}

生成具有縮進(jìn)功能的JSON(pretty-print)

Marshal 函數(shù)生成最小的內(nèi)聯(lián)JSON內(nèi)容,沒(méi)有任何格式化。你可以使用MarshalIndent 函數(shù)來(lái)編碼具有縮進(jìn)功能的可讀JSON。下面的代碼為上一個(gè)結(jié)構(gòu)對(duì)象生成了prettified JSON。

package main
import (
    "fmt"
    "encoding/json"
)
type Seller struct {
    Id int `json:"id"`
    Name string `json:"name"`
    CountryCode string `json:"country_code"`
}
type Product struct {
    Id int `json:"id"`
    Name string `json:"name"`
    Seller Seller `json:"seller"`
    Price int `json:"price"`
}
func main() {
    book := Product{
        Id: 50,
        Name: "Writing Book",
        Seller: Seller {1, "ABC Company", "US"},
        Price: 100,
    }
    bytes, _ := json.MarshalIndent(book, "", "\t")
    fmt.Println(string(bytes))
}

一旦你運(yùn)行上述代碼,它將打印出一個(gè)格式化的JSON結(jié)構(gòu),如下圖所示。

這里我們使用Tab字符(\t)進(jìn)行縮進(jìn)。你可以根據(jù)你的要求使用四個(gè)空格、兩個(gè)空格、八個(gè)空格等進(jìn)行格式化。

忽略JSON輸出中的特定字段

早些時(shí)候,我們使用結(jié)構(gòu)標(biāo)簽來(lái)重命名JSON鍵。我們也可以使用結(jié)構(gòu)標(biāo)簽來(lái)省略特定字段。如果我們使用json:”-” 作為標(biāo)簽,相關(guān)的結(jié)構(gòu)字段將不會(huì)被用于編碼。另外,如果我們?cè)诮Y(jié)構(gòu)標(biāo)簽名稱字符串中使用,omitempty ,如果相關(guān)字段的值為空,則不會(huì)被用于編碼。

下面的代碼省略了產(chǎn)品標(biāo)識(shí)符的編碼。此外,它還從輸出中省略了空的國(guó)家代碼值。

package main
import (
    "fmt"
    "encoding/json"
)
type Seller struct {
    Id int `json:"id"`
    Name string `json:"name"`
    CountryCode string `json:"country_code,omitempty"`
}
type Product struct {
    Id int `json:"-"`
    Name string `json:"name"`
    Seller Seller `json:"seller"`
    Price int `json:"price"`
}
func main() {
    products := []Product{
        Product {
            Id: 50,
            Name: "Writing Book",
            Seller: Seller {Id: 1, Name: "ABC Company", CountryCode: "US"},
            Price: 100,
        },
        Product {
            Id: 51,
            Name: "Kettle",
            Seller: Seller {Id: 20, Name: "John Store"},
            Price: 500,
        },
    }
    bytes, _ := json.MarshalIndent(products, "", "\t")
    fmt.Println(string(bytes))
}

上述代碼產(chǎn)生以下輸出。注意,它不包含產(chǎn)品標(biāo)識(shí)符和第二項(xiàng)的國(guó)家代碼鍵。

解除偽裝。將JSON轉(zhuǎn)換為Go對(duì)象

在Go環(huán)境中,JSON文檔的解碼過(guò)程被稱為unmarshaling。我們可以使用Unmarshal 函數(shù)來(lái)將JSON轉(zhuǎn)換為Go對(duì)象。Unmarshal 函數(shù)的語(yǔ)法如下。

func Unmarshal(data []byte, v interface{}) error

它接受兩個(gè)參數(shù):一個(gè)JSON內(nèi)容的字節(jié)片和一個(gè)空的接口引用。如果在解碼過(guò)程中出現(xiàn)錯(cuò)誤,該函數(shù)可能會(huì)返回一個(gè)錯(cuò)誤。Unmarshal 函數(shù)不創(chuàng)建和返回Go對(duì)象,所以我們必須傳遞一個(gè)引用來(lái)存儲(chǔ)解碼后的內(nèi)容。

解除對(duì)簡(jiǎn)單JSON結(jié)構(gòu)的封存

類似于JSON的marshaling,我們可以解封Go的原始數(shù)據(jù)類型,如整數(shù)、字符串、浮點(diǎn)數(shù)和布爾。但同樣的,由于原始數(shù)據(jù)解密在大多數(shù)軟件開(kāi)發(fā)項(xiàng)目中沒(méi)有真正的使用案例,我們先將下面的鍵值結(jié)構(gòu)解碼為Go結(jié)構(gòu)。

{
    "width": 500,
    "height": 200,
    "title": "Hello Go!"
}

下面的代碼將上述JSON結(jié)構(gòu)解碼成一個(gè)結(jié)構(gòu)。

package main
import (
    "fmt"
    "encoding/json"
)
type Window struct {
    Width int `json:"width"`
    Height int `json:"height"`
    Title string `json:"title"`
}
func main() {
    jsonInput := `{
        "width": 500,
        "height": 200,
        "title": "Hello Go!"
    }`
    var window Window
    err := json.Unmarshal([]byte(jsonInput), &window)

    if err != nil {
        fmt.Println("JSON decode error!")
        return
    }

    fmt.Println(window) // {500 200 Hello Go!}
}

jsonInput 變量將JSON內(nèi)容作為一個(gè)多行字符串保存。因此,在用byte[]() 類型轉(zhuǎn)換語(yǔ)法將其傳遞給Unmarshal 函數(shù)之前,我們必須將其轉(zhuǎn)換為字節(jié)片狀。在這里,我們檢查了返回的錯(cuò)誤對(duì)象的值以檢測(cè)解析錯(cuò)誤。

在這種情況下,上述JSON標(biāo)簽是可選的,因?yàn)镚o編碼/json包通常將JSON字段映射為結(jié)構(gòu)字段,并進(jìn)行不區(qū)分大小寫的匹配。

同樣地,我們也可以將JSON結(jié)構(gòu)解碼為Go映射。請(qǐng)看下面的示例代碼。

package main
import (
    "fmt"
    "encoding/json"
)
func main() {
    jsonInput := `{
        "apples": 10,
        "mangos": 20,
        "grapes": 20
    }`
    var fruitBasket map[string] int
    err := json.Unmarshal([]byte(jsonInput), &fruitBasket)

    if err != nil {
        fmt.Println("JSON decode error!")
        return
    }

    fmt.Println(fruitBasket) // map[apples:10 grapes:20 mangos:20]
}

解除復(fù)雜數(shù)據(jù)結(jié)構(gòu)的束縛

之前的解密例子向你展示了如何對(duì)簡(jiǎn)單的JSON結(jié)構(gòu)進(jìn)行解密。我們?cè)谲浖_(kāi)發(fā)項(xiàng)目中經(jīng)常要對(duì)復(fù)雜的嵌套JSON結(jié)構(gòu)進(jìn)行解碼。下面的例子演示了如何從一個(gè)JSON格式的產(chǎn)品列表中填充Go對(duì)象。

package main
import (
    "fmt"
    "encoding/json"
)
type Product struct {
    Id int `json:"id"`
    Name string `json:"name"`
    Seller struct {
        Id int `json:"id"`
        Name string `json:"name"`
        CountryCode string `json:"country_code"`
    } `json:"seller"`
    Price int `json:"price"`
}
func main() {
    jsonInput := `[
    {
        "id":50,
        "name":"Writing Book",
        "seller":{
            "id":1,
            "name":"ABC Company",
            "country_code":"US"
        },
        "price":100
    },
    {
        "id":51,
        "name":"Kettle",
        "seller":{
            "id":20,
            "name":"John Store",
            "country_code":"DE"
        },
        "price":500
    }]
    `
    var products []Product
    err := json.Unmarshal([]byte(jsonInput), &products)

    if err != nil {
        fmt.Println("JSON decode error!")
        return
    }

    fmt.Println(products)
    // [{50 Writing Book {1 ABC Company US} 100} {51 Kettle {20 John Store DE} 500}]
}

如上面的代碼所示,我們需要先通過(guò)檢查JSON輸入來(lái)定義一個(gè)結(jié)構(gòu)。當(dāng)你處理大型復(fù)雜的JSON結(jié)構(gòu)時(shí),這個(gè)過(guò)程是一個(gè)耗時(shí)的任務(wù)。因此,你可以使用JSON-to-Go這樣的在線工具,根據(jù)JSON輸入創(chuàng)建結(jié)構(gòu)定義。

也有一種方法可以在Go中不創(chuàng)建結(jié)構(gòu)而訪問(wèn)解析后的值。你可以通過(guò)為JSON對(duì)象創(chuàng)建map[string]interface{} 類型對(duì)象來(lái)動(dòng)態(tài)訪問(wèn)任何值,但這種方法會(huì)導(dǎo)致非常復(fù)雜、質(zhì)量較差的源代碼。

不過(guò),你可以通過(guò)下面的示例代碼檢查動(dòng)態(tài)JSON值的訪問(wèn),以達(dá)到實(shí)驗(yàn)?zāi)康?。但是,在沒(méi)有建立適當(dāng)?shù)腉o結(jié)構(gòu)的情況下,不要在生產(chǎn)軟件系統(tǒng)中使用這種方法,因?yàn)樗鼤?huì)產(chǎn)生復(fù)雜和難以測(cè)試的代碼。

package main
import (
    "fmt"
    "encoding/json"
)
func main() {
    jsonInput := `[
    {
        "id":50,
        "name":"Writing Book",
        "seller":{
            "id":1,
            "name":"ABC Company",
            "country_code":"US"
        },
        "price":100
    },
    {
        "id":51,
        "name":"Kettle",
        "seller":{
            "id":20,
            "name":"John Store",
            "country_code":"DE"
        },
        "price":500
    }]
    `
    var objMap []map[string]interface{}
    err := json.Unmarshal([]byte(jsonInput), &objMap)

    if err != nil {
        fmt.Println("JSON decode error!")
        return
    }

    fmt.Println("Price of the second product:", objMap\[1\]["price"])
}

上面的代碼在沒(méi)有Go結(jié)構(gòu)的情況下打印了第二個(gè)產(chǎn)品項(xiàng)目的價(jià)格。

從文件系統(tǒng)中讀取JSON文件

我們?cè)谇懊娴睦又惺褂昧擞簿幋a的JSON字符串進(jìn)行演示。但是,在實(shí)踐中,我們從不同的來(lái)源加載JSON字符串:從文件系統(tǒng),通過(guò)互聯(lián)網(wǎng),通過(guò)本地網(wǎng)絡(luò)位置,等等。大多數(shù)程序員通常使用JSON格式來(lái)存儲(chǔ)文件系統(tǒng)上的配置細(xì)節(jié)。

讓我們寫一些Go代碼,從文件中讀取和解碼JSON數(shù)據(jù),并將其轉(zhuǎn)換成Go對(duì)象。首先,創(chuàng)建一個(gè)名為config.json 的文件并輸入以下內(nèi)容。

{
    "timeout": 50.30,
    "pluginsPath": "~/plugins/",
    "window": {
        "width": 500,
        "height": 200,
        "x": 500,
        "y": 500
    }
}

現(xiàn)在,運(yùn)行以下代碼,將上述JSON文件解碼為合適的結(jié)構(gòu)。

package main
import (
    "fmt"
    "io/ioutil"
    "encoding/json"
)
type Config struct {
    Timeout float32
    PluginsPath string
    Window struct {
        Width int
        Height int
        X int
        Y int
    }
}
func main() {

    bytes, err := ioutil.ReadFile("config.json")

    if err != nil {
        fmt.Println("Unable to load config file!")
        return
    }

    var config Config
    err = json.Unmarshal(bytes, &config)

    if err != nil {
        fmt.Println("JSON decode error!")
        return
    }

    fmt.Println(config) // {50.3 ~/plugins/ {500 200 500 500}}
}

上面的代碼用ioutil.ReadFile 函數(shù)將JSON文件內(nèi)容讀成字節(jié),并將數(shù)據(jù)記錄解碼到Config 結(jié)構(gòu)中。

將JSON文件寫到文件系統(tǒng)中

在前面的例子中,我們通過(guò)Println 函數(shù)將編碼后的JSON內(nèi)容打印到控制臺(tái)?,F(xiàn)在我們可以通過(guò)ioutil.WriteFile 函數(shù)將這些JSON字符串保存為文件,如下圖所示。

package main
import (
    "io/ioutil"
    "encoding/json"
)
type Window struct {
    Width int `json:"width"`
    Height int `json:"height"`
    X int `json:"x"`
    Y int `json:"y"`
}
type Config struct {
    Timeout float32 `json:"timeout"`
    PluginsPath string `json:"pluginsPath"`
    Window Window `json:"window"`
}
func main() {
    config := Config {
        Timeout: 40.420,
        PluginsPath: "~/plugins/etc",
        Window: Window {500, 200, 20, 20},
    }
    bytes, _ := json.MarshalIndent(config, "", "  ")
    ioutil.WriteFile("config.json", bytes, 0644)
}

上面的代碼通過(guò)將config 對(duì)象編碼為JSON對(duì)象來(lái)寫入config.json 。這里我們使用了兩個(gè)空格來(lái)縮進(jìn),并通過(guò)使用結(jié)構(gòu)標(biāo)簽將結(jié)構(gòu)字段轉(zhuǎn)換為駱駝大寫的JSON鍵。

自定義抓取和解除抓取

Go json包非常靈活,它提供了覆蓋編碼和解碼過(guò)程的功能。當(dāng)您在編碼/解碼過(guò)程中需要將JSON數(shù)據(jù)記錄從一種格式轉(zhuǎn)換為另一種格式時(shí),這些功能很有幫助。

自定義編排

假設(shè)你正在用Go編寫一個(gè)聯(lián)系人管理應(yīng)用程序,你提供一個(gè)功能給所有用戶下載JSON格式的聯(lián)系人列表。假設(shè)由于安全策略的原因,你不能讓非管理員用戶看到所有的電子郵件ID。在這種情況下,你可以通過(guò)Go json包中的自定義marshaling功能來(lái)定制JSON編碼過(guò)程,如下所示。

package main
import (
    "fmt"
    "encoding/json"
    "strings"
)
type Person struct {
    Name string `json:"name"`
    Age int `json:"age"`
    Email string `json:"-"`
}
func main() {
    persons := []Person {
            Person {"James Henrick", 25, "james.h@gmail.com"},
            Person {"David Rick", 30, "rick.dvd@yahoo.com"},
    }
    bytes, _ := json.MarshalIndent(persons, "", "  ")
    fmt.Println(string(bytes))
}
func (p *Person) MarshalJSON() ([]byte, error) {
    type PersonAlias Person
    return json.Marshal(&struct{
        *PersonAlias
        Email string `json:"email"`
    }{
        PersonAlias: (*PersonAlias)(p),
        Email: strings.Repeat("*", 4) + "@mail.com", // alter email
    })
}

上面的代碼輸出了所有的聯(lián)系方式,但由于安全策略的原因,它改變了原始的電子郵件地址。請(qǐng)注意,這里我們需要從Person 類型中創(chuàng)建另一個(gè)類型(alias),因?yàn)槿绻覀冊(cè)噲D為原來(lái)的Person 類型調(diào)用Marshal 函數(shù),由于編碼過(guò)程的遞歸實(shí)現(xiàn),程序?qū)⑦M(jìn)入無(wú)限循環(huán)。一旦你運(yùn)行上述代碼片斷,你會(huì)看到如下的輸出。

自定義解密

Go json包也可以讓你自定義JSON解碼過(guò)程。假設(shè)你需要處理一個(gè)JSON配置文件,并需要在解碼過(guò)程中轉(zhuǎn)換一些值。假設(shè)一個(gè)配置字段說(shuō)的是開(kāi)爾文的溫度,但你需要用攝氏度來(lái)存儲(chǔ)具體數(shù)值。

請(qǐng)看下面的代碼,它實(shí)現(xiàn)了自定義解密。

package main
import (
    "fmt"
    "encoding/json"
)
type Config struct {
    FunctionName string 
    Temperature float32
}
func main() {
    jsonInput := `{
        "functionName": "triggerModule",
        "temperature": 4560.32
    }`
    var config Config
    err := json.Unmarshal([]byte(jsonInput), &config)

    if err != nil {
        fmt.Println("JSON decode error!")
        return
    }

    fmt.Println(config) // {triggerModule 4287.17}
}
func (c *Config) UnmarshalJSON(data []byte) error {
    type ConfigAlias Config
    tmp := struct {
        Temperature float32
        *ConfigAlias
    }{
        ConfigAlias: (*ConfigAlias)(c),
    }
    if err := json.Unmarshal(data, &tmp); err != nil {
        return err
    }
    c.Temperature = tmp.Temperature - 273.15
    return nil
}

上述代碼通過(guò)將temperature 字段的值從開(kāi)爾文轉(zhuǎn)換為攝氏度來(lái)解讀JSON。這里我們還需要?jiǎng)?chuàng)建另一個(gè)類型(alias),以避免無(wú)限循環(huán),這與自定義的marshaling類似。

總結(jié)

在本教程中,我們通過(guò)實(shí)際例子討論了Go中的JSON編碼(marshaling)和解碼(unmarshaling)。JSON是一種廣泛使用的、獨(dú)立于語(yǔ)言的編碼格式。因此,幾乎所有基于Go的網(wǎng)絡(luò)框架都在內(nèi)部處理JSON編碼和解碼。例如,GinHTTP框架允許你使用json包直接向API函數(shù)發(fā)送一個(gè)結(jié)構(gòu)體,而不需要手動(dòng)進(jìn)行marshaling。

然而,你可以在你的Go程序中使用Go json包,而不需要消耗第三方庫(kù),因?yàn)閖son包是標(biāo)準(zhǔn)庫(kù)的一部分。另外,Go json包還有一些更快的替代品(根據(jù)這個(gè)基準(zhǔn))。但是,json包是標(biāo)準(zhǔn)庫(kù)的一部分,由Go開(kāi)發(fā)團(tuán)隊(duì)維護(hù)。因此,Go開(kāi)發(fā)團(tuán)隊(duì)會(huì)在即將發(fā)布的版本中提高編碼/json包的性能。

到此這篇關(guān)于在Go中使用JSON(附demo)的文章就介紹到這了,更多相關(guān)Go使用JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang的引用類型和指針的使用與區(qū)別

    Golang的引用類型和指針的使用與區(qū)別

    本文詳細(xì)介紹了Golang中的引用類型和指針的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • 詳解Golang中零拷貝的原理以及實(shí)踐

    詳解Golang中零拷貝的原理以及實(shí)踐

    零拷貝技術(shù)相信大家都有所耳聞,但是本文不僅會(huì)講述零拷貝技術(shù)的原理,并將從實(shí)際代碼出發(fā),看看零拷貝技術(shù)在golang中的應(yīng)用,現(xiàn)在讓我們開(kāi)始吧
    2023-07-07
  • Go語(yǔ)言Goroutinue和管道效率詳解

    Go語(yǔ)言Goroutinue和管道效率詳解

    這篇文章主要為大家介紹了Go語(yǔ)言Goroutinue和管道效率使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Go語(yǔ)言操作etcd的示例詳解

    Go語(yǔ)言操作etcd的示例詳解

    etcd是使用Go語(yǔ)言開(kāi)發(fā)的一個(gè)開(kāi)源的、高可用的分布式key—value存儲(chǔ)系統(tǒng),可以用于配置共享和服務(wù)的注冊(cè)和發(fā)現(xiàn),下面我們就來(lái)看看Go語(yǔ)言是如何操作etcd的吧
    2024-03-03
  • Golang數(shù)組的傳遞詳解

    Golang數(shù)組的傳遞詳解

    今天小編就為大家分享一篇關(guān)于Golang數(shù)組的傳遞詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • 一文詳解Golang的中間件設(shè)計(jì)模式

    一文詳解Golang的中間件設(shè)計(jì)模式

    最近在看一些rpc框架的使用原理和源碼的時(shí)候,對(duì)中間件的實(shí)現(xiàn)非常感興趣,所以這篇文章就來(lái)和大家聊聊Golang的中間件設(shè)計(jì)模式,希望對(duì)大家有所幫助
    2023-03-03
  • Golang 按行讀取文件的三種方法小結(jié)

    Golang 按行讀取文件的三種方法小結(jié)

    本文主要介紹了Golang 按行讀取文件的三種方法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go標(biāo)準(zhǔn)庫(kù)strconv實(shí)現(xiàn)string類型與其他基本數(shù)據(jù)類型之間轉(zhuǎn)換

    Go標(biāo)準(zhǔn)庫(kù)strconv實(shí)現(xiàn)string類型與其他基本數(shù)據(jù)類型之間轉(zhuǎn)換

    這篇文章主要為大家介紹了Go標(biāo)準(zhǔn)庫(kù)strconv實(shí)現(xiàn)string類型與其他基本數(shù)據(jù)類型之間轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Go實(shí)現(xiàn)跨平臺(tái)的藍(lán)牙聊天室示例詳解

    Go實(shí)現(xiàn)跨平臺(tái)的藍(lán)牙聊天室示例詳解

    這篇文章主要為大家介紹了Go實(shí)現(xiàn)跨平臺(tái)的藍(lán)牙聊天室示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 詳解Go 1.22 for循環(huán)的兩處重要更新

    詳解Go 1.22 for循環(huán)的兩處重要更新

    這篇文章主要詳細(xì)介紹了Go 1.22 for循環(huán)的兩處重要更新,Go 1.22 版本于 2024 年 2 月 6 日發(fā)布,引入了幾個(gè)重要的特性和改進(jìn),在語(yǔ)言層面上,這個(gè)版本對(duì) for 循環(huán)進(jìn)行了兩處更新,本文將會(huì)對(duì) for 循環(huán)的兩個(gè)更新進(jìn)行介紹,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

邵东县| 石首市| 荥经县| 思茅市| 额敏县| 澄迈县| 百色市| 牙克石市| 宣恩县| 新蔡县| 济南市| 石景山区| 句容市| 察雅县| 黄浦区| 于都县| 承德县| 边坝县| 嵩明县| 吴旗县| 晋城| 无锡市| 桃源县| 云浮市| 贵定县| 甘德县| 囊谦县| 宁乡县| 丽水市| 滦平县| 靖边县| 琼海市| 方正县| 抚顺市| 吴川市| 自治县| 确山县| 台湾省| 年辖:市辖区| 聊城市| 桦南县|