欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang MarshalJson的實現(xiàn)

 更新時間:2025年03月04日 09:17:54   作者:get200  
本文主要介紹了golang MarshalJson的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

在 Go 語言中,MarshalJSON 是一個接口方法,允許自定義類型在進行 JSON 編碼時提供自定義的序列化邏輯。通過實現(xiàn) MarshalJSON 方法,你可以控制結(jié)構(gòu)體或其他類型在轉(zhuǎn)換為 JSON 時的表現(xiàn)。

基本用法

當你想要自定義某個類型的 JSON 表現(xiàn)時,可以實現(xiàn) json.Marshaler 接口,該接口只包含一個方法 MarshalJSON。實現(xiàn)該方法后,使用 json.Marshal 函數(shù)時會自動調(diào)用你定義的 MarshalJSON 方法。

示例

以下是一個示例,展示如何自定義結(jié)構(gòu)體的 JSON 序列化:

package main

import (
    "encoding/json"
    "fmt"
)

// 定義一個結(jié)構(gòu)體
type User struct {
    Name  string
    Age   int
    Email string
}

// 為 User 實現(xiàn) MarshalJSON 方法
func (u User) MarshalJSON() ([]byte, error) {
    // 自定義 JSON 輸出格式
    return json.Marshal(struct {
        FullName string `json:"name"`
        Age      int    `json:"age"`
        Email    string `json:"email_address"`
    }{
        FullName: u.Name,
        Age:      u.Age,
        Email:    u.Email,
    })
}

func main() {
    user := User{Name: "Alice", Age: 30, Email: "alice@example.com"}

    // Marshal 用戶對象為 JSON
    jsonData, err := json.Marshal(user)
    if err != nil {
        fmt.Println("Error marshaling to JSON:", err)
        return
    }

    fmt.Println(string(jsonData)) // 輸出: {"name":"Alice","age":30,"email_address":"alice@example.com"}
}

解釋

  • 定義結(jié)構(gòu)體:我們定義了一個 User 結(jié)構(gòu)體,包含 NameAge 和 Email 字段。
  • 實現(xiàn) MarshalJSON 方法:我們?yōu)?nbsp;User 結(jié)構(gòu)體實現(xiàn)了 MarshalJSON 方法。在這個方法中,我們自定義了 JSON 輸出格式。
  • 自定義輸出:在 MarshalJSON 方法中,我們使用匿名結(jié)構(gòu)體來定義最終的 JSON 格式。
  • 使用 json.Marshal:在 main 函數(shù)中,我們創(chuàng)建了一個 User 實例,并使用 json.Marshal 將其轉(zhuǎn)換為 JSON 字符串。

注意事項

  • 錯誤處理MarshalJSON 方法應(yīng)返回 error,以便在序列化過程中可以處理潛在的錯誤。
  • 遞歸調(diào)用:在 MarshalJSON 方法中,如果調(diào)用 json.Marshal,需要確保所處理的結(jié)構(gòu)體不會遞歸調(diào)用自身的 MarshalJSON 方法。

Marshal函數(shù)將會遞歸遍歷整個對象,依次按成員類型對這個對象進行編碼。

類型轉(zhuǎn)換規(guī)則如下:

  • bool類型:轉(zhuǎn)換為JSON的Boolean
  • 整數(shù)、浮點數(shù)等數(shù)值類型: 轉(zhuǎn)換為JSON的Number
  • string類型: 轉(zhuǎn)換為JSON的字符串(帶""引號)
  • struct類型:轉(zhuǎn)換為JSON的Object,再根據(jù)各個成員的類型遞歸打包
  • 數(shù)組或切片類型: 轉(zhuǎn)換為JSON的Array
  • []byte類型: 會先進行base64編碼然后轉(zhuǎn)換為JSON字符串
  • map類型:轉(zhuǎn)換為JSON的Object,key必須是string
  • interface{}類型: 按照內(nèi)部的實際類型進行轉(zhuǎn)換
  • nil類型: 轉(zhuǎn)為JSON的null
  • channel,func等類型: 會返回UnsupportedTypeError

從golang到j(luò)son:

golangjson
boolBoolean
int、float等數(shù)字Number
stringString
[]byte(base64編碼)String
structObject,再遞歸打包
array/sliceArray
mapObject
interface{}按實際類型轉(zhuǎn)換
nilnull
channel,funcUnsupportedTypeError

從json到golang:

jsongolang
Booleanbool
Numberfloat64
Stringstring
Array[]interface{}
Objectmap[string]interface{}
nullnil

避坑

json.marshal使用不當,會存在base64編碼問題問題出現(xiàn)在:[]byte 在json.marshal時會進行base64 encoding處理

解決辦法:使用json.RawMessagejson.RawMessage其實就是[]byte類型的重定義??梢赃M行強制類型轉(zhuǎn)換。

現(xiàn)在有這么一種場景,結(jié)構(gòu)體中的其中一個字段的格式是未知的:

type Command struct {  
    ID   int  
    Cmd  string  
    Args *json.RawMessage  
}  

使用json.RawMessage的話,Args字段在Unmarshal時不會被解析,直接將字節(jié)數(shù)據(jù)賦值給Args。我們可以能先解包第一層的JSON數(shù)據(jù),然后根據(jù)Cmd的值,再確定Args的具體類型進行第二次Unmarshal。

注意:一定要使用指針類型*json.RawMessage,否則在Args會被認為是[]byte類型,在打包時會被打包成base64編碼的字符串。

使用interface{}, interface{}類型在Unmarshal時,會自動將JSON轉(zhuǎn)換為對應(yīng)的數(shù)據(jù)類型:

JSON的boolean: 轉(zhuǎn)換為bool
JSON的數(shù)值: 轉(zhuǎn)換為float64
JSON的字符串: 轉(zhuǎn)換為string
JSON的Array: 轉(zhuǎn)換為[]interface{}
JSON的Object: 轉(zhuǎn)換為map[string]interface{}
JSON的null: 轉(zhuǎn)換為nil

需要注意的有兩個:

  • 一是所有的JSON數(shù)值自動轉(zhuǎn)換為float64類型,使用時需要再手動轉(zhuǎn)換為需要的int,int64等類型。
  • 二是JSON的object自動轉(zhuǎn)換為map[string]interface{}類型,訪問時直接用JSON Object的字段名作為key進行訪問。在不知道JSON數(shù)據(jù)的格式時,可以使用interface{}。

自定義類型:如果希望自己定義對象的打包解包方式,可以實現(xiàn)以下的接口:

type Marshaler interface {  
    MarshalJSON() ([]byte, error)  
}  
type Unmarshaler interface {  
    UnmarshalJSON([]byte) error  
}  

實現(xiàn)該接口的對象需要將自己的數(shù)據(jù)打包和解包。如果實現(xiàn)了該接口,json在打包解包時則會調(diào)用自定義的方法,不再對該對象進行其他處理。

總結(jié)

通過實現(xiàn) MarshalJSON 方法,可以為 Go 的自定義類型提供靈活的 JSON 序列化控制。這使得在與 JSON 數(shù)據(jù)交互時,可以更好地控制數(shù)據(jù)的結(jié)構(gòu)和格式。

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

相關(guān)文章

  • go的strings用法小結(jié)

    go的strings用法小結(jié)

    strings 是 Go 語言標準庫中提供的一個包,用于處理字符串相關(guān)的操作,本文主要介紹了go的strings用法小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • golang 占位符和fmt常見輸出介紹

    golang 占位符和fmt常見輸出介紹

    這篇文章主要介紹了golang 占位符和fmt常見輸出介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go泛型之泛型約束示例詳解

    Go泛型之泛型約束示例詳解

    這篇文章主要給大家介紹了關(guān)于Go泛型之泛型約束的相關(guān)資料,泛型是靜態(tài)語言中的一種編程方式,這種編程方式可以讓算法不再依賴于某個具體的數(shù)據(jù)類型,而是通過將數(shù)據(jù)類型進行參數(shù)化,以達到算法可復(fù)用的目的,需要的朋友可以參考下
    2023-12-12
  • Go的gin參數(shù)校驗中的validator庫詳解

    Go的gin參數(shù)校驗中的validator庫詳解

    這篇文章主要介紹了Go的gin參數(shù)校驗之validator庫,使用 validator 以后,只需要在定義結(jié)構(gòu)體時使用 binding 或 validate tag標識相關(guān)校驗規(guī)則,就可以進行參數(shù)校驗了,而不用自己單獨去寫常見的校驗規(guī)則,需要的朋友可以參考下
    2023-08-08
  • Go?tablewriter庫提升命令行輸出專業(yè)度實例詳解

    Go?tablewriter庫提升命令行輸出專業(yè)度實例詳解

    命令行工具大家都用過,如果是運維人員可能會編寫命令行工具來完成各種任務(wù),命令行輸出的美觀和易讀性往往容易被忽視,很爛的輸出會讓人感覺不專業(yè),本文將介紹Go語言中牛逼的實戰(zhàn)工具tablewriter庫,使你在命令行輸出中展現(xiàn)出專業(yè)的一面
    2023-11-11
  • golang gopm get -g -v 無法獲取第三方庫的解決方案

    golang gopm get -g -v 無法獲取第三方庫的解決方案

    這篇文章主要介紹了golang gopm get -g -v 無法獲取第三方庫的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 輕松入門:使用Golang開發(fā)跨平臺GUI應(yīng)用

    輕松入門:使用Golang開發(fā)跨平臺GUI應(yīng)用

    Golang是一種強大的編程語言,它的并發(fā)性和高性能使其成為開發(fā)GUI桌面應(yīng)用的理想選擇,Golang提供了豐富的標準庫和第三方庫,可以輕松地創(chuàng)建跨平臺的GUI應(yīng)用程序,通過使用Golang的GUI庫,開發(fā)人員可以快速構(gòu)建具有豐富用戶界面和交互功能的應(yīng)用程序,需要的朋友可以參考下
    2023-10-10
  • golang簡單獲取上傳文件大小的實現(xiàn)代碼

    golang簡單獲取上傳文件大小的實現(xiàn)代碼

    這篇文章主要介紹了golang簡單獲取上傳文件大小的方法,涉及Go語言文件傳輸及文件屬性操作的相關(guān)技巧,需要的朋友可以參考下
    2016-07-07
  • 使用golang引入外部包的三種方式:go get, go module, vendor目錄

    使用golang引入外部包的三種方式:go get, go module, ve

    這篇文章主要介紹了使用golang引入外部包的三種方式:go get, go module, vendor目錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Golang中Json的序列化和反序列化的使用

    Golang中Json的序列化和反序列化的使用

    本文主要介紹了Golang中Json的序列化和反序列化的使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評論