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

Go語言中json操作的實現(xiàn)

 更新時間:2025年09月26日 11:13:54   作者:n8n  
本文主要介紹了Go語言中的json操作的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

?? 一、JSON 與 Go 類型對應(yīng)關(guān)系

理解 JSON 類型與 Go 類型的映射是處理 JSON 的基礎(chǔ):

JSON 類型Go 類型說明
對象 (object)struct, map[string]T鍵值對集合
數(shù)組 (array)[]T (切片), [n]T (數(shù)組)值的有序集合,通常使用切片更靈活
字符串 (string)string
數(shù)字 (number)int, float64 等注意:JSON 中的數(shù)字默認(rèn)解碼為 float64
布爾 (boolean)bool
nullnil

??? 二、基本操作:編碼與解碼

Go 使用標(biāo)準(zhǔn)庫 encoding/json 進(jìn)行 JSON 處理。

編碼 (序列化,Marshal):使用 json.Marshal 將 Go 數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為 JSON 字節(jié)切片 ([]byte)。

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string `json:"name"` // 通過標(biāo)簽指定JSON字段名
    Age  int    `json:"age"`
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    jsonBytes, err := json.Marshal(p)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(jsonBytes)) // 輸出:{"name":"Alice","age":30}
}

解碼 (反序列化,Unmarshal):使用 json.Unmarshal 將 JSON 字節(jié)切片解析回 Go 數(shù)據(jù)結(jié)構(gòu)。

jsonStr := `{"name":"Bob","age":25}`
var p2 Person
err = json.Unmarshal([]byte(jsonStr), &p2) // 注意傳遞指針
if err != nil {
    panic(err)
}
fmt.Printf("%+v\n", p2) // 輸出:{Name:Bob Age:25}

格式化輸出:使用 json.MarshalIndent 生成帶縮進(jìn)的格式化 JSON,便于閱讀。

jsonBytes, err := json.MarshalIndent(p, "", "  ") // 前綴為空,縮進(jìn)為兩個空格
if err != nil {
    panic(err)
}
fmt.Println(string(jsonBytes))
/* 輸出:
{
  "name": "Alice",
  "age": 30
}
*/

?? 三、結(jié)構(gòu)體標(biāo)簽(Struct Tags)的運用

結(jié)構(gòu)體標(biāo)簽是控制 JSON 序列化和反序列化行為的關(guān)鍵。

自定義字段名:使用 json:"field_name" 指定 JSON 字段名。

type Product struct {
    ProductID int    `json:"id"`      // JSON中字段名為 "id"
    Name      string `json:"name"`    // JSON中字段名為 "name"
}

忽略字段

type User struct {
    Name     string `json:"name"`
    Password string `json:"-"` // 序列化時忽略密碼字段
}
type User struct {
    Name  string `json:"name"`
    Email string `json:"email,omitempty"` // 如果Email為空,則序列化時不包含此字段
    Age   int    `json:"age,omitempty"`   // 如果Age為0,則序列化時不包含此字段
}
  • 永久忽略:使用 json:"-",該字段不會參與 JSON 序列化。
  • 條件忽略(空值):使用 omitempty,當(dāng)字段為零值時(如空字符串、零值、nil指針等),序列化時省略該字段。

字符串形式的數(shù)字:有時需要將數(shù)字類型以字符串形式序列化,或從字符串形式的數(shù)字反序列化,可以使用 ,string 標(biāo)簽選項。

type MyData struct {
    Num int `json:"num,string"` // 序列化為 {"num": "123"}, 從 {"num": "123"} 反序列化
}

注意:此標(biāo)簽僅適用于 int, float, bool 等類型與字符串形式的互轉(zhuǎn),且 JSON 中對應(yīng)的值必須是帶引號的字符串。

?? 四、處理未知結(jié)構(gòu)或動態(tài) JSON

當(dāng)你無法預(yù)知 JSON 的確切結(jié)構(gòu)時,有兩種主要方法:

使用 map[string]interface{}:適合快速訪問,但需要類型斷言,安全性較低。

jsonStr := `{"name":"Alice","age":30,"hobbies":["reading","traveling"]}`
var data map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &data)
if err != nil {
    panic(err)
}
name := data["name"].(string) // 類型斷言
age := data["age"].(float64)   // JSON數(shù)字默認(rèn)轉(zhuǎn)為float64
hobbies := data["hobbies"].([]interface{})
fmt.Println(name, age, hobbies[0])

使用 json.RawMessage:延遲解析,允許你先處理已知部分,再按需解析未知部分,更靈活安全。

type Message struct {
    Name  string          `json:"name"`
    Extra json.RawMessage `json:"extra"` // 原始JSON字節(jié),暫不解析
}
var msg Message
json.Unmarshal([]byte(jsonStr), &msg)
// 之后根據(jù)條件再解析 Extra 字段

? 五、處理時間類型(time.Time)

time.Time 類型默認(rèn)序列化為 RFC 3339 格式的字符串。你也可以為 time.Time 定義自定義的 MarshalerUnmarshaler 接口實現(xiàn),以適應(yīng)特定的時間格式。

type Event struct {
    Name      string    `json:"name"`
    Timestamp time.Time `json:"timestamp"` // 默認(rèn)格式:2006-01-02T15:04:05Z07:00
}
event := Event{Name: "Party", Timestamp: time.Now()}
jsonData, _ := json.Marshal(event)
fmt.Println(string(jsonData)) // {"name":"Party","timestamp":"2023-10-01T10:00:00Z"}

?? 六、流式編碼與解碼

處理大型 JSON 數(shù)據(jù)或 IO 流(如 HTTP 請求體、文件)時,使用 json.Encoderjson.Decoder 可以提高內(nèi)存效率。

流式編碼(寫入)

file, err := os.Create("output.json")
if err != nil {
    panic(err)
}
defer file.Close()
encoder := json.NewEncoder(file)
encoder.SetIndent("", "  ") // 設(shè)置縮進(jìn)
err = encoder.Encode(data) // 將數(shù)據(jù)直接編碼并寫入文件
if err != nil {
    panic(err)
}

流式解碼(讀?。?/strong>

file, err := os.Open("large_data.json")
if err != nil {
    panic(err)
}
defer file.Close()
decoder := json.NewDecoder(file)
for {
    var item MyStruct
    if err := decoder.Decode(&item); err == io.EOF {
        break // 流結(jié)束
    } else if err != nil {
        panic(err)
    }
    // 處理每一個 item
    fmt.Println(item)
}

?? 七、自定義序列化與反序列化

通過實現(xiàn) json.Marshalerjson.Unmarshaler 接口,你可以完全控制特定類型的編碼和解碼邏輯。

type Status int

const (
    Unknown Status = iota
    Active
    Inactive
)

// 實現(xiàn) MarshalJSON,將 Status 轉(zhuǎn)換為字符串
func (s Status) MarshalJSON() ([]byte, error) {
    var str string
    switch s {
    case Active:
        str = "active"
    case Inactive:
        str = "inactive"
    default:
        str = "unknown"
    }
    return json.Marshal(str)
}

// 實現(xiàn) UnmarshalJSON,將字符串轉(zhuǎn)換回 Status
func (s *Status) UnmarshalJSON(data []byte) error {
    var str string
    if err := json.Unmarshal(data, &str); err != nil {
        return err
    }
    switch str {
    case "active":
        *s = Active
    case "inactive":
        *s = Inactive
    default:
        *s = Unknown
    }
    return nil
}

? 八、性能優(yōu)化建議

  1. 避免使用 interface{}:盡可能使用明確類型的結(jié)構(gòu)體,而不是 map[string]interface{},這能減少反射開銷并提高類型安全。
  2. 重用 json.Decoder:在循環(huán)中解碼多個 JSON 對象時,復(fù)用 json.Decoder 實例。
  3. 預(yù)分配切片:如果你知道解碼后數(shù)組的大致大小,預(yù)分配切片容量可以減少擴容帶來的開銷。
  4. **使用 json.RawMessage`` 延遲解析**:對于部分不需要立即處理的 JSON 數(shù)據(jù),可以先存儲為 json.RawMessage`,等到需要時再解析,從而減少不必要的解析開銷。

?? 總結(jié)與建議

Go 語言的 encoding/json 庫提供了強大而靈活的 JSON 處理能力。掌握從基礎(chǔ)編碼解碼到高級技巧,能讓你更自如地應(yīng)對各種數(shù)據(jù)處理場景。記住,明確的結(jié)構(gòu)體定義優(yōu)于 map[string]interface{},善用結(jié)構(gòu)體標(biāo)簽?zāi)芫?xì)控制序列化行為,而 流式處理 則是處理大數(shù)據(jù)的利器。

到此這篇關(guān)于Go語言中json操作的實現(xiàn)的文章就介紹到這了,更多相關(guān)Go語言 json操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang文件讀取-按指定BUFF大小讀取方式

    golang文件讀取-按指定BUFF大小讀取方式

    這篇文章主要介紹了golang文件讀取-按指定BUFF大小讀取方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 一文帶你搞懂Golang依賴注入的設(shè)計與實現(xiàn)

    一文帶你搞懂Golang依賴注入的設(shè)計與實現(xiàn)

    在現(xiàn)代的 web 框架里面,基本都有實現(xiàn)了依賴注入的功能,可以讓我們很方便地對應(yīng)用的依賴進(jìn)行管理。今天我們來看看 go 里面實現(xiàn)依賴注入的一種方式,感興趣的可以了解一下
    2023-01-01
  • GO的基礎(chǔ)知識掃盲注意事項

    GO的基礎(chǔ)知識掃盲注意事項

    這篇文章主要介紹了GO的基礎(chǔ)知識注意事項,本文是GO語言小白的掃盲文,主要講解了go語言的基本知識,GO程序目錄結(jié)構(gòu),GO程序包的導(dǎo)入與別名運用,GO內(nèi)置關(guān)鍵字,GO注釋方法需要的朋友可以參考下
    2022-12-12
  • Golang標(biāo)準(zhǔn)庫os/exec執(zhí)行外部命令并獲取其輸出包代碼示例

    Golang標(biāo)準(zhǔn)庫os/exec執(zhí)行外部命令并獲取其輸出包代碼示例

    這篇文章主要為大家介紹了Golang標(biāo)準(zhǔn)庫os/exec執(zhí)行外部命令并獲取其輸出包代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 深入理解Go泛型里的 ~[]E

    深入理解Go泛型里的 ~[]E

    本文主要介紹了深入理解Go泛型里的 ~[]E,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • Windows10系統(tǒng)下安裝Go環(huán)境詳細(xì)步驟

    Windows10系統(tǒng)下安裝Go環(huán)境詳細(xì)步驟

    Go語言是谷歌推出的一款全新的編程語言,可以在不損失應(yīng)用程序性能的情況下極大的降低代碼的復(fù)雜性,這篇文章主要給大家介紹了關(guān)于Windows10系統(tǒng)下安裝Go環(huán)境的詳細(xì)步驟,需要的朋友可以參考下
    2023-11-11
  • Go語言:打造優(yōu)雅數(shù)據(jù)庫單元測試的實戰(zhàn)指南

    Go語言:打造優(yōu)雅數(shù)據(jù)庫單元測試的實戰(zhàn)指南

    Go語言數(shù)據(jù)庫單元測試入門:聚焦高效、可靠的數(shù)據(jù)庫代碼驗證!想要確保您的Go應(yīng)用數(shù)據(jù)層堅如磐石嗎?本指南將手把手教您如何利用Go進(jìn)行數(shù)據(jù)庫單元測試,輕松揪出隱藏的bug,打造無懈可擊的數(shù)據(jù)處理邏輯,一起來探索吧!
    2024-01-01
  • 使用Go基于WebSocket構(gòu)建千萬級視頻直播彈幕系統(tǒng)的代碼詳解

    使用Go基于WebSocket構(gòu)建千萬級視頻直播彈幕系統(tǒng)的代碼詳解

    這篇文章主要介紹了使用Go基于WebSocket構(gòu)建千萬級視頻直播彈幕系統(tǒng),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Go1.21新增maps包的用法詳解

    Go1.21新增maps包的用法詳解

    maps?包提供了幾個非常有用的用于操作?map?類型(任何類型的?map)的函數(shù),本文為大家整理了部分函數(shù)的具體用法,感興趣的小伙伴可以了解一下
    2023-08-08
  • Golang中優(yōu)秀的消息隊列NSQ基礎(chǔ)安裝及使用詳解

    Golang中優(yōu)秀的消息隊列NSQ基礎(chǔ)安裝及使用詳解

    這篇文章主要介紹了Golang中優(yōu)秀的消息隊列NSQ基礎(chǔ)安裝及使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論

海原县| 雅江县| 额尔古纳市| 双桥区| 张家界市| 抚远县| 明光市| 古丈县| 弥渡县| 玉龙| 海兴县| 彭阳县| 侯马市| 德惠市| 武夷山市| 蛟河市| 德庆县| 寿宁县| 积石山| 无锡市| 河西区| 托克逊县| 睢宁县| 陆河县| 南城县| 浙江省| 新干县| 封开县| 金昌市| 团风县| 广元市| 阿拉尔市| 吉林省| 崇文区| 托里县| 定兴县| 平利县| 全州县| 赣州市| 密云县| 肃南|