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

Go?結(jié)構(gòu)體序列化的實(shí)現(xiàn)

 更新時(shí)間:2022年01月24日 09:31:32   作者:Go語(yǔ)言由淺入深  
本文主要介紹了Go?結(jié)構(gòu)體序列化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文,我們將回到之前寫(xiě)的showMovieHandler方法,并更新它以返回一個(gè)JSON響應(yīng),表示系統(tǒng)中的單個(gè)電影信息。類似于:

{
? ? "id": 123,
? ? "title": "Casablanca",?
? ? "runtime": 102,?
? ? "genres": [
? ? ? ? "drama",?
? ? ? ? "romance",?
? ? ? ? "war"
? ? ],
? ? "version": 1?
}

我們不使用map序列化來(lái)創(chuàng)建這個(gè)JSON對(duì)象(就像我們?cè)谏弦还?jié)中所做的那樣),這次我們將編碼一個(gè)自定義的Movie結(jié)構(gòu)體。

首先,需要定義一個(gè)Movie結(jié)構(gòu)體。我們將在一個(gè)新internal/data包中完成此操作,該包稍后將擴(kuò)展用來(lái)封裝項(xiàng)目中所有自定義數(shù)據(jù)類型以及與數(shù)據(jù)庫(kù)交互的邏輯。

如果您按照文章步驟操作,請(qǐng)創(chuàng)建一個(gè)新的internal/data目錄,其中包含一個(gè)movies.go文件:

$ mkdir internal/data
$ touch internal/data/movies.go

在這個(gè)新文件中,定義Movie結(jié)構(gòu),像這樣:

File: internal/data/movies.go

package main

import (
? ? "time"
)

type Movie struct {
? ? ID ? ? ? ? ? ? int64 ? ? ?//唯一整數(shù)ID
? ? CreatedAt ? ? ?time.Time ?//創(chuàng)建電影到數(shù)據(jù)庫(kù)的時(shí)間
? ? Title ? ? ? ? ?string ? ? //電影標(biāo)題
? ? Year ? ? ? ? ? int32 ? ? ?//電影發(fā)布年份
? ? Runtime ? ? ? ?int32 ? ? ?//電影時(shí)長(zhǎng)
? ? Genres ? ? ? ? []string ? //電影類型(愛(ài)情片、喜劇片等)
? ? Version ? ? ? ?int32 ? ? ?//版本號(hào)從1開(kāi)始,每更新一次遞增
}

這里需要指出的是,Movie結(jié)構(gòu)體中的所有字段都是可導(dǎo)出的(即以大寫(xiě)字母開(kāi)頭),這對(duì)于Go的encoding/json包可見(jiàn)是必要的。在將結(jié)構(gòu)體編碼為JSON時(shí),不會(huì)包含任何未導(dǎo)出的字段。

現(xiàn)在結(jié)構(gòu)體已經(jīng)定義完成,讓我們更新showMovieHandler處理程序來(lái)初始化一個(gè)Movie結(jié)構(gòu)體實(shí)例,然后使用writeJSON()幫助函數(shù)將其作為JSON響應(yīng)發(fā)送給客戶端。

實(shí)現(xiàn)很簡(jiǎn)單:

File: cmd/api/movies.go

package main

import (
    "fmt"
    "net/http"
    "time"

    "greenlight.alexedwards.net/internal/data"
)

func (app *application) showMovieHandler(w http.ResponseWriter, r *http.Request) {
    id, err := app.readIDParam(r)
    if err != nil {
        http.NotFound(w, r)
        return
    }

    //創(chuàng)建一個(gè)Move結(jié)構(gòu)體實(shí)例,包含從請(qǐng)求URL中解析的ID虛構(gòu)的數(shù)據(jù)。注意這里故意沒(méi)有設(shè)置Year字段
    movie := date.Movie{
        ID: id,
        CreateAt: time.now(),
        Title: "Casablanca",
        Runtime: 102,
        Genres: []string{"drama", "romance", "war"},
        Version: 1,
    }

    //將結(jié)構(gòu)體序列化為JSON并以HTTP響應(yīng)發(fā)送給客戶端
    err = app.writeJSON(w, http.StatusOK, movie, nil)
    if err != nil {
         app.logger.Println(err)
         http.Error(w, "The server encountered a problem and could not process your request", http.StatusInternalServerError)
    }
}

ok,下面試試!

重啟API,然后在瀏覽器中訪問(wèn)localhost:4000/v1/movies/123。你應(yīng)該會(huì)看到一個(gè)類似這樣的JSON響應(yīng):

在這個(gè)返回結(jié)果中,有幾件有趣的事情需要指出:

  • Movie結(jié)構(gòu)體被編碼成一個(gè)JSON對(duì)象,字段名和值作為鍵/值對(duì)。
  • 默認(rèn)情況下,JSON對(duì)象中的鍵等于結(jié)構(gòu)體中的字段名(ID、CreatedAt、Title等等)。我們稍后將討論如何自定義JSON鍵。
  • 如果結(jié)構(gòu)體實(shí)例字段沒(méi)有顯式賦值,那么字段零值將序列化為json值??梢栽谏厦娴捻憫?yīng)中看到——我們沒(méi)有在Go代碼中為Year字段設(shè)置值,但它仍然以0值出現(xiàn)在JSON輸出中。

更改JSON對(duì)象中的鍵

在Go中序列化結(jié)構(gòu)體的一個(gè)好處是,您可以通過(guò)使用struct標(biāo)簽注釋字段來(lái)定制JSON。

struct標(biāo)簽最常見(jiàn)的用途可能是更改JSON對(duì)象中出現(xiàn)的鍵名稱。當(dāng)你的結(jié)構(gòu)體字段名不適合面向公眾展示,或者你想在JSON輸出中使用另一種大小寫(xiě)樣式時(shí),這是很有用的。

為了說(shuō)明如何實(shí)現(xiàn),對(duì)Movies結(jié)構(gòu)體字段打標(biāo)簽,使用蛇形格式:

File: internal/data/movies.go

//使用標(biāo)記對(duì)Movie結(jié)構(gòu)進(jìn)行注釋,以控制json編碼的key顯示方式。
type Movie struct {
? ? ID ? ? ? int64 ? ? `json:"id"`
? ? CreateAt time.Time `json:"created_at"`
? ? Title ? ?string ? ?`json:"title"`
? ? Year ? ? int32 ? ? `json:"year"`
? ? Runtime ?int32 ? ? `json:"runtime"`
? ? Genres ? []string ?`json:"genres"`
? ? Version ?int32 ? ? `json:"version"`
}

如果你重啟服務(wù)器并再次訪問(wèn)localhost:4000/v1/movies/123,應(yīng)該會(huì)看到一個(gè)類似于這樣的帶有蛇形鍵的響應(yīng):

在JSON對(duì)象中隱藏結(jié)構(gòu)體字段

在定義結(jié)構(gòu)體時(shí)候,通過(guò)使用omitempty可以控制對(duì)應(yīng)字段在JSON中的可見(jiàn)性。當(dāng)您不希望JSON輸出中出現(xiàn)特定的結(jié)構(gòu)體字段時(shí),可以使用-(連字符)指令。這對(duì)包含和用戶不相關(guān)的內(nèi)部系統(tǒng)信息的字段或不想公開(kāi)的敏感信息(如密碼哈希值)非常有用。

相反,當(dāng)且僅當(dāng)struct字段值為空時(shí),omitempty指令會(huì)在JSON輸出中隱藏字段,其中empty被定義為:

  • 等于false,0或“”
  • 空數(shù)組,切片或map
  • nil指針或接口值為nil

為了演示如何使用這些指令,我們對(duì)Movie結(jié)構(gòu)進(jìn)行更多的改造。CreatedAt字段與我們的最終用戶無(wú)關(guān),所以我們使用-指令在輸出中將其隱藏。我們還將使用omitempty指令在輸出中隱藏Year、Runtime和types字段,當(dāng)且僅當(dāng)它們?yōu)榭諘r(shí)生效。

繼續(xù)并像下面這樣更新struct標(biāo)簽:

File:interface/data/movies.go

package data

....

type Movie struct {
? ? ID ? ? ? int64 ? ? `json:"id"`
? ? CreateAt time.Time `json:"-"` ? ? ? //使用-指令
? ? Title ? ?string ? ?`json:"title"`
? ? Year ? ? int32 ? ? `json:"year,omitempty"` ? ? ? ? ? ?//添加omitempty
? ? Runtime ?int32 ? ? `json:"runtime,omitempty"` ? ? ? ? //添加omitempty
? ? Genres ? []string ?`json:"genres,omitempty"` ? ? ? ? ?//添加omitempty
? ? Version ?int32 ? ? `json:"version"`
}

如果你想使用omitempty而不改變鍵名,那么你可以在struct標(biāo)簽中保留它為空-如:json:",omitempty"。注意,逗號(hào)是必要的。

現(xiàn)在,當(dāng)你重新啟動(dòng)應(yīng)用程序并刷新你的web瀏覽器時(shí),你應(yīng)該會(huì)看到如下響應(yīng):

我們可以在這里看到,CreatedAt結(jié)構(gòu)字段不再出現(xiàn)在JSON中,而且Year字段(值為0)也沒(méi)有出現(xiàn),這要感謝omitempty指令。其他字段使用了omitempty不受影響(例如Runtime和Genres)。

注意:您還可以通過(guò)簡(jiǎn)單地將結(jié)構(gòu)體字段設(shè)置為不可導(dǎo)出來(lái)防止它出現(xiàn)在JSON序列化中。但使用json:“-“標(biāo)記通常是一個(gè)更好的選擇:明確告知閱讀代碼的人,你不希望該字段包含在json。

舊版本的go vet如果你試圖在未導(dǎo)出的字段上使用struct標(biāo)記會(huì)引發(fā)錯(cuò)誤,但現(xiàn)在在go 1.16中已經(jīng)修復(fù)了這個(gè)問(wèn)題。

附加內(nèi)容

結(jié)構(gòu)體標(biāo)簽string指令

最后一個(gè)不太常用的struct標(biāo)記指令是string??梢允褂眠@個(gè)標(biāo)簽明確表示字段值序列化成JSON字符串類型。例如,如果我們希望Runtime字段的值表示為一個(gè)JSON字符串 (而不是數(shù)字)我們可以像這樣使用string指令:

type Movie struct {
? ? ID ? ? ? int64 ? ? `json:"id"`
? ? CreateAt time.Time `json:"-"` ? ? ? //使用-指令
? ? Title ? ?string ? ?`json:"title"`
? ? Year ? ? int32 ? ? `json:"year,omitempty"` ??
? ? Runtime ?Runtime ? `json:"runtime,omitempty,string"`?
? ? Genres ? []string ?`json:"genres,omitempty"` ? ? ??
? ? Version ?int32 ? ? `json:"version"`
}

JSON序列化結(jié)果如下所示:

{
"id": 123,
"title": "Casablanca",
"runtime": "102", ? //這是字符串
"genres": [
? ? "drama",?
? ? "romance",?
? ? "war"
? ? ],
"version": 1?
}

注意string指令只對(duì)int, uint, float*或bool類型的字段有效。對(duì)于任何其他類型的結(jié)構(gòu)體字段沒(méi)有作用。

到此這篇關(guān)于Go 結(jié)構(gòu)體序列化的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go 結(jié)構(gòu)體序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語(yǔ)言context包功能及操作使用詳解

    go語(yǔ)言context包功能及操作使用詳解

    這篇文章主要為大家介紹了go語(yǔ)言context包功能及操作使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go語(yǔ)言的四數(shù)相加等于指定數(shù)算法

    go語(yǔ)言的四數(shù)相加等于指定數(shù)算法

    這篇文章主要介紹了go語(yǔ)言的四數(shù)相加等于指定數(shù)算法的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • 深入理解Go gin框架中Context的Request和Writer對(duì)象

    深入理解Go gin框架中Context的Request和Writer對(duì)象

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言的gin框架中Context的Request和Writer對(duì)象,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Go語(yǔ)言有一定的幫助,快跟隨小編一起學(xué)習(xí)一下吧
    2023-04-04
  • Golang科學(xué)計(jì)數(shù)法轉(zhuǎn)換string數(shù)字輸出的實(shí)現(xiàn)

    Golang科學(xué)計(jì)數(shù)法轉(zhuǎn)換string數(shù)字輸出的實(shí)現(xiàn)

    最近接手一個(gè)商城運(yùn)單號(hào)模塊,接手后發(fā)現(xiàn)有部分運(yùn)單號(hào)返回給前端是按照科學(xué)計(jì)數(shù)法的方式返回,本文就介紹一下Golang科學(xué)計(jì)數(shù)法轉(zhuǎn)換string數(shù)字輸出,感興趣的可以了解一下
    2021-07-07
  • Go語(yǔ)言中普通函數(shù)與方法的區(qū)別分析

    Go語(yǔ)言中普通函數(shù)與方法的區(qū)別分析

    這篇文章主要介紹了Go語(yǔ)言中普通函數(shù)與方法的區(qū)別,以實(shí)例形式對(duì)比分析了普通函數(shù)與方法使用時(shí)的區(qū)別與相關(guān)技巧,需要的朋友可以參考下
    2015-02-02
  • GoLang函數(shù)棧的使用詳細(xì)講解

    GoLang函數(shù)棧的使用詳細(xì)講解

    這篇文章主要介紹了GoLang函數(shù)棧的使用,我們的代碼會(huì)被編譯成機(jī)器指令并寫(xiě)入到可執(zhí)行文件,當(dāng)程序執(zhí)行時(shí),可執(zhí)行文件被加載到內(nèi)存,這些機(jī)器指令會(huì)被存儲(chǔ)到虛擬地址空間中的代碼段,在代碼段內(nèi)部,指令是低地址向高地址堆積的
    2023-02-02
  • Golang 中的可測(cè)試示例函數(shù)(Example Function)詳解

    Golang 中的可測(cè)試示例函數(shù)(Example Function)詳解

    這篇文章詳細(xì)講解了 Golang 中的可測(cè)試示例函數(shù),示例函數(shù)類似于單元測(cè)試函數(shù),但沒(méi)有  *testing 類型的參數(shù),編寫(xiě)示例函數(shù)也是很容易的,本文就通過(guò)代碼示例給大家介紹一下Golang的可測(cè)試示例函數(shù),需要的朋友可以參考下
    2023-07-07
  • Go語(yǔ)言中的Slice學(xué)習(xí)總結(jié)

    Go語(yǔ)言中的Slice學(xué)習(xí)總結(jié)

    這篇文章主要介紹了Go語(yǔ)言中的Slice學(xué)習(xí)總結(jié),本文講解了Slice的定義、Slice的長(zhǎng)度和容量、Slice是引用類型、Slice引用傳遞發(fā)生“意外”等內(nèi)容,需要的朋友可以參考下
    2014-11-11
  • GO比較兩個(gè)對(duì)象是否相同實(shí)戰(zhàn)案例

    GO比較兩個(gè)對(duì)象是否相同實(shí)戰(zhàn)案例

    我們時(shí)常有比較兩個(gè)值是否相等的需求,下面這篇文章主要給大家介紹了關(guān)于GO比較兩個(gè)對(duì)象是否相同的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 使用Go語(yǔ)言實(shí)現(xiàn)找出兩個(gè)大文件中相同的記錄

    使用Go語(yǔ)言實(shí)現(xiàn)找出兩個(gè)大文件中相同的記錄

    這篇文章主要為大家詳細(xì)介紹了使用Go語(yǔ)言實(shí)現(xiàn)找出兩個(gè)大文件中相同的記錄的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10

最新評(píng)論

彩票| 韶关市| 阿勒泰市| 大同市| 同心县| 大港区| 宕昌县| 民丰县| 巍山| 白沙| 渭源县| 施秉县| 宜君县| 囊谦县| 灵台县| 仙桃市| 丰镇市| 澄江县| 阳江市| 广宗县| 昌宁县| 甘南县| 交口县| 叙永县| 张北县| 刚察县| 济阳县| 克山县| 云梦县| 湟源县| 莲花县| 西乌| 五大连池市| 新泰市| 石嘴山市| 岳西县| 广元市| 宜兰市| 平顺县| 大宁县| 东阿县|