亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go?結構體序列化的實現(xiàn)

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

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

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

我們不使用map序列化來創(chuàng)建這個JSON對象(就像我們在上一節(jié)中所做的那樣),這次我們將編碼一個自定義的Movie結構體。

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

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

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

在這個新文件中,定義Movie結構,像這樣:

File: internal/data/movies.go

package main

import (
? ? "time"
)

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

這里需要指出的是,Movie結構體中的所有字段都是可導出的(即以大寫字母開頭),這對于Go的encoding/json包可見是必要的。在將結構體編碼為JSON時,不會包含任何未導出的字段。

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

實現(xià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)建一個Move結構體實例,包含從請求URL中解析的ID虛構的數(shù)據(jù)。注意這里故意沒有設置Year字段
    movie := date.Movie{
        ID: id,
        CreateAt: time.now(),
        Title: "Casablanca",
        Runtime: 102,
        Genres: []string{"drama", "romance", "war"},
        Version: 1,
    }

    //將結構體序列化為JSON并以HTTP響應發(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,然后在瀏覽器中訪問localhost:4000/v1/movies/123。你應該會看到一個類似這樣的JSON響應:

在這個返回結果中,有幾件有趣的事情需要指出:

  • Movie結構體被編碼成一個JSON對象,字段名和值作為鍵/值對。
  • 默認情況下,JSON對象中的鍵等于結構體中的字段名(ID、CreatedAt、Title等等)。我們稍后將討論如何自定義JSON鍵。
  • 如果結構體實例字段沒有顯式賦值,那么字段零值將序列化為json值。可以在上面的響應中看到——我們沒有在Go代碼中為Year字段設置值,但它仍然以0值出現(xiàn)在JSON輸出中。

更改JSON對象中的鍵

在Go中序列化結構體的一個好處是,您可以通過使用struct標簽注釋字段來定制JSON。

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

為了說明如何實現(xiàn),對Movies結構體字段打標簽,使用蛇形格式:

File: internal/data/movies.go

//使用標記對Movie結構進行注釋,以控制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"`
}

如果你重啟服務器并再次訪問localhost:4000/v1/movies/123,應該會看到一個類似于這樣的帶有蛇形鍵的響應:

在JSON對象中隱藏結構體字段

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

相反,當且僅當struct字段值為空時,omitempty指令會在JSON輸出中隱藏字段,其中empty被定義為:

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

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

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

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標簽中保留它為空-如:json:",omitempty"。注意,逗號是必要的。

現(xiàn)在,當你重新啟動應用程序并刷新你的web瀏覽器時,你應該會看到如下響應:

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

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

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

附加內(nèi)容

結構體標簽string指令

最后一個不太常用的struct標記指令是string??梢允褂眠@個標簽明確表示字段值序列化成JSON字符串類型。例如,如果我們希望Runtime字段的值表示為一個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序列化結果如下所示:

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

注意string指令只對int, uint, float*或bool類型的字段有效。對于任何其他類型的結構體字段沒有作用。

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

相關文章

  • GO語言中創(chuàng)建切片的三種實現(xiàn)方式

    GO語言中創(chuàng)建切片的三種實現(xiàn)方式

    這篇文章主要介紹了GO語言中創(chuàng)建切片的三種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • golang中命令行庫cobra的使用方法示例

    golang中命令行庫cobra的使用方法示例

    這篇文章主要給大家介紹了關于golang中命令行庫cobra的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • Golang 使用http Client下載文件的實現(xiàn)方法

    Golang 使用http Client下載文件的實現(xiàn)方法

    今天小編就為大家分享一篇Golang 使用http Client下載文件的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Go網(wǎng)絡編程TCP抓包實操示例探究

    Go網(wǎng)絡編程TCP抓包實操示例探究

    作為一名軟件開發(fā)者,網(wǎng)絡編程是必備知識,本文通過?Go?語言實現(xiàn)?TCP?套接字編程,并結合?tcpdump?工具,展示它的三次握手、數(shù)據(jù)傳輸以及四次揮手的過程,幫助讀者更好地理解?TCP?協(xié)議與?Go?網(wǎng)絡編程
    2024-01-01
  • 舉例詳解Go語言中os庫的常用函數(shù)用法

    舉例詳解Go語言中os庫的常用函數(shù)用法

    這篇文章主要介紹了Go語言中os庫的常用函數(shù)用法,os函數(shù)的使用是Go語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-10-10
  • 深入了解Golang中reflect反射的使用

    深入了解Golang中reflect反射的使用

    這篇文章主要介紹了深入了解Golang中reflect反射的使用,Go語言中的反射是一種機制,可以在運行時動態(tài)地獲取類型信息和操作對象,以及調(diào)用對象的方法和屬性等,需要詳細了解可以參考下文
    2023-05-05
  • 淺析go中Ticker,Timer和Tick的用法與區(qū)別

    淺析go中Ticker,Timer和Tick的用法與區(qū)別

    在go面試的時候,面試官經(jīng)常會問time包的Ticker,Timer以及Tick的區(qū)別,一般在超時控制的時候用的比較多,今天就跟隨小編一起來詳細學一下這幾個的區(qū)別吧
    2023-10-10
  • 談論Go 什么時候會觸發(fā) GC問題

    談論Go 什么時候會觸發(fā) GC問題

    Go 語言作為一門新語言,在早期經(jīng)常遭到唾棄的就是在垃圾回收(下稱:GC)機制中 STW(Stop-The-World)的時間過長。下面文章就對此話題展開,感興趣的小伙伴可以參考下面文章的內(nèi)容
    2021-09-09
  • Go 語言數(shù)據(jù)結構之雙鏈表學習教程

    Go 語言數(shù)據(jù)結構之雙鏈表學習教程

    這篇文章主要為大家介紹了Go 語言數(shù)據(jù)結構之雙鏈表學習教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • golang實現(xiàn)簡易的分布式系統(tǒng)方法

    golang實現(xiàn)簡易的分布式系統(tǒng)方法

    這篇文章主要介紹了golang實現(xiàn)簡易的分布式系統(tǒng)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10

最新評論