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

Go語言struct要使用?tags的原因解析

 更新時(shí)間:2023年03月11日 15:15:39   作者:yongxinz  
這篇文章主要介紹了為什么?Go?語言?struct?要使用?tags,在本文中,我們將探討為什么 Go 語言中需要使用 struct tags,以及 struct tags 的使用場景和優(yōu)勢,需要的朋友可以參考下

在 Go 語言中,struct 是一種常見的數(shù)據(jù)類型,它可以用來表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。在 struct 中,我們可以定義多個(gè)字段,每個(gè)字段可以有不同的類型和名稱。

除了這些基本信息之外,Go 還提供了 struct tags,它可以用來指定 struct 中每個(gè)字段的元信息。

在本文中,我們將探討為什么 Go 語言中需要使用 struct tags,以及 struct tags 的使用場景和優(yōu)勢。

struct tags 的使用

struct tags 使用還是很廣泛的,特別是在 json 序列化,或者是數(shù)據(jù)庫 ORM 映射方面。

在定義上,它以 key:value 的形式出現(xiàn),跟在 struct 字段后面,除此之外,還有以下幾點(diǎn)需要注意:

使用反引號

在聲明 struct tag 時(shí),使用反引號 ` 包圍 tag 的值,可以防止轉(zhuǎn)義字符的影響,使 tag 更容易讀取和理解。例如:

type User struct {
    ID    int    `json:"id" db:"id"`
    Name  string `json:"name" db:"name"`
    Email string `json:"email" db:"email"`
}

避免使用空格

在 struct tag 中,應(yīng)該避免使用空格,特別是在 tag 名稱和 tag 值之間。使用空格可能會導(dǎo)致編碼或解碼錯誤,并使代碼更難以維護(hù)。例如:

// 不規(guī)范的寫法
type User struct {
    ID    int    `json: "id" db: "id"`
    Name  string `json: "name" db: "name"`
    Email string `json: "email" db: "email"`
}

// 規(guī)范的寫法
type User struct {
    ID    int    `json:"id" db:"id"`
    Name  string `json:"name" db:"name"`
    Email string `json:"email" db:"email"`
}

避免重復(fù)

在 struct 中,應(yīng)該避免重復(fù)使用同一個(gè) tag 名稱。如果重復(fù)使用同一個(gè) tag 名稱,編譯器可能會無法識別 tag,從而導(dǎo)致編碼或解碼錯誤。例如:

// 不規(guī)范的寫法
type User struct {
    ID    int    `json:"id" db:"id"`
    Name  string `json:"name" db:"name"`
    Email string `json:"email" db:"name"`
}

// 規(guī)范的寫法
type User struct {
    ID    int    `json:"id" db:"id"`
    Name  string `json:"name" db:"name"`
    Email string `json:"email" db:"email"`
}

使用標(biāo)準(zhǔn)化的 tag 名稱

為了使 struct tag 更加標(biāo)準(zhǔn)化和易于維護(hù),應(yīng)該使用一些標(biāo)準(zhǔn)化的 tag 名稱。

例如,對于序列化和反序列化,可以使用 jsonxml、yaml 等;對于數(shù)據(jù)庫操作,可以使用 db。

type User struct {
    ID       int    `json:"id" db:"id"`
    Name     string `json:"name" db:"name"`
    Password string `json:"-" db:"password"` // 忽略該字段
    Email    string `json:"email" db:"email"`
}

其中,Password 字段后面的 - 表示忽略該字段,也就是說該字段不會被序列化或反序列化。

多個(gè) tag 值

如果一個(gè)字段需要指定多個(gè) tag 值,可以使用 , 將多個(gè) tag 值分隔開。例如:

type User struct {
    ID        int    `json:"id" db:"id"`
    Name      string `json:"name" db:"name"`
    Email     string `json:"email,omitempty" db:"email,omitempty"`
}

其中 omitempty 表示如果該字段值為空,則不序列化該字段。

struct tags 的原理

Go 的反射庫提供了一些方法,可以讓我們在程序運(yùn)行時(shí)獲取和解析結(jié)構(gòu)體標(biāo)簽。

介紹這些方法之前,先來看看 reflect.StructField ,它是描述結(jié)構(gòu)體字段的數(shù)據(jù)類型。定義如下:

type StructField struct {
    Name      string      // 字段名
    Type      Type        // 字段類型
    Tag       StructTag   // 字段標(biāo)簽
}

結(jié)構(gòu)體中還有一些其他字段,被我省略了,只保留了和本文相關(guān)的。

在結(jié)構(gòu)體的反射中,我們經(jīng)常使用 reflect.TypeOf 獲取類型信息,然后使用 Type.FieldType.FieldByName() 獲取結(jié)構(gòu)體字段的 reflect.StructField,然后根據(jù) StructField 中的信息做進(jìn)一步處理。

例如,可以通過 StructField.Tag.Get 方法獲取結(jié)構(gòu)體字段的標(biāo)簽值。

下面看一段代碼:

package main

import (
    "fmt"
    "reflect"
)

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

type Manager struct {
    Title string `json:"title"`
    User
}

func main() {
    m := Manager{Title: "Manager", User: User{Name: "Alice", Age: 25}}

    mt := reflect.TypeOf(m)

    // 獲取 User 字段的 reflect.StructField
    userField, _ := mt.FieldByName("User")
    fmt.Println("Field 'User' exists:", userField.Name, userField.Type)

    // 獲取 User.Name 字段的 reflect.StructField
    nameField, _ := userField.Type.FieldByName("Name")
    tag := nameField.Tag.Get("json")
    fmt.Println("User.Name tag:", tag)
}

運(yùn)行以上代碼,輸出結(jié)果如下:

Field 'User' exists: User {string int}
User.Name tag: "name"

struct tags 的優(yōu)勢

使用 struct tag 的主要優(yōu)勢之一是可以在運(yùn)行時(shí)通過反射來訪問和操作 struct 中的字段。

比如在 Go Web 開發(fā)中,常常需要將 HTTP 請求中的參數(shù)綁定到一個(gè) struct 中。這時(shí),我們可以使用 struct tag 指定每個(gè)字段對應(yīng)的參數(shù)名稱、驗(yàn)證規(guī)則等信息。在接收到 HTTP 請求時(shí),就可以使用反射機(jī)制讀取這些信息,并根據(jù)信息來驗(yàn)證參數(shù)是否合法。

另外,在將 struct 序列化為 JSON 或者其他格式時(shí),我們也可以使用 struct tag 來指定每個(gè)字段在序列化時(shí)的名稱和規(guī)則。

此外,使用 struct tag 還可以提高代碼的可讀性和可維護(hù)性。在一個(gè)大型的項(xiàng)目中,struct 中的字段通常會包含很多不同的元信息,比如數(shù)據(jù)庫中的表名、字段名、索引、驗(yàn)證規(guī)則等等。

如果沒有 struct tag,我們可能需要將這些元信息放在注釋中或者在代碼中進(jìn)行硬編碼。這樣會讓代碼變得難以維護(hù)和修改。而使用 struct tag 可以將這些元信息與 struct 字段緊密關(guān)聯(lián)起來,使代碼更加清晰和易于維護(hù)。

常用的 struct tags

在 Go 的官方 wiki 中,有一個(gè)常用的 struct tags 的庫的列表,我復(fù)制在下面了,感興趣的同學(xué)可以看看源碼,再繼續(xù)深入學(xué)習(xí)。

TagDocumentation
xmlhttps://pkg.go.dev/encoding/xml
jsonhttps://pkg.go.dev/encoding/json
asn1https://pkg.go.dev/encoding/asn1
reformhttps://pkg.go.dev/gopkg.in/reform.v1
dynamodbhttps://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/#Marshal
bigqueryhttps://pkg.go.dev/cloud.google.com/go/bigquery
datastorehttps://pkg.go.dev/cloud.google.com/go/datastore
spannerhttps://pkg.go.dev/cloud.google.com/go/spanner
bsonhttps://pkg.go.dev/labix.org/v2/mgo/bsonhttps://pkg.go.dev/go.mongodb.org/mongo-driver/bson/bsoncodec
gormhttps://pkg.go.dev/github.com/jinzhu/gorm
yamlhttps://pkg.go.dev/gopkg.in/yaml.v2
tomlhttps://pkg.go.dev/github.com/pelletier/go-toml
validatehttps://github.com/go-playground/validator
mapstructurehttps://pkg.go.dev/github.com/mitchellh/mapstructure
parserhttps://pkg.go.dev/github.com/alecthomas/participle
protobufhttps://github.com/golang/protobuf
dbhttps://github.com/jmoiron/sqlx
urlhttps://github.com/google/go-querystring
featurehttps://github.com/nikolaydubina/go-featureprocessing

以上就是本文的全部內(nèi)容,如果覺得還不錯的話歡迎點(diǎn)贊,轉(zhuǎn)發(fā)和關(guān)注,感謝支持。

參考文章:

https://github.com/golang/go/wiki/Well-known-struct-tags

到此這篇關(guān)于為什么 Go 語言 struct 要使用 tags的文章就介紹到這了,更多相關(guān)Go 語言 struct 要使用 tags內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用go語言解析xml的實(shí)現(xiàn)方法(必看篇)

    使用go語言解析xml的實(shí)現(xiàn)方法(必看篇)

    下面小編就為大家?guī)硪黄褂胓o語言解析xml的實(shí)現(xiàn)方法(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Golang服務(wù)中context超時(shí)處理的方法詳解

    Golang服務(wù)中context超時(shí)處理的方法詳解

    在Go語言中,Context是一個(gè)非常重要的概念,它存在于一個(gè)完整的業(yè)務(wù)生命周期內(nèi),Context類型是一個(gè)接口類型,在實(shí)際應(yīng)用中,我們可以使用Context包來傳遞請求的元數(shù)據(jù),本文將給大家介紹Golang服務(wù)中context超時(shí)處理的方法和超時(shí)原因,需要的朋友可以參考下
    2023-05-05
  • Go gorilla securecookie庫的安裝使用詳解

    Go gorilla securecookie庫的安裝使用詳解

    這篇文章主要介紹了Go gorilla securecookie庫的安裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang sync.Map原理深入分析講解

    Golang sync.Map原理深入分析講解

    go中map數(shù)據(jù)結(jié)構(gòu)不是線程安全的,即多個(gè)goroutine同時(shí)操作一個(gè)map,則會報(bào)錯,因此go1.9之后誕生了sync.Map,sync.Map思路來自java的ConcurrentHashMap
    2022-12-12
  • 關(guān)于golang利用channel和goroutine完成統(tǒng)計(jì)素?cái)?shù)的思路

    關(guān)于golang利用channel和goroutine完成統(tǒng)計(jì)素?cái)?shù)的思路

    這篇文章主要介紹了golang利用channel和goroutine完成統(tǒng)計(jì)素?cái)?shù)的思路詳解,通過思路圖分析及實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • Go語言大揭秘:適用于哪些類型的項(xiàng)目開發(fā)?

    Go語言大揭秘:適用于哪些類型的項(xiàng)目開發(fā)?

    想知道Go編程語言適合開發(fā)哪些類型的項(xiàng)目嗎?無論是網(wǎng)絡(luò)服務(wù)、分布式系統(tǒng)還是嵌入式設(shè)備,Go都能輕松應(yīng)對,本文將帶你了解Go在各種場景下的應(yīng)用,讓你更好地選擇和使用Go進(jìn)行開發(fā),需要的朋友可以參考下
    2024-01-01
  • Go?CSV包實(shí)現(xiàn)結(jié)構(gòu)體和csv內(nèi)容互轉(zhuǎn)工具詳解

    Go?CSV包實(shí)現(xiàn)結(jié)構(gòu)體和csv內(nèi)容互轉(zhuǎn)工具詳解

    這篇文章主要介紹了Go?CSV包實(shí)現(xiàn)結(jié)構(gòu)體和csv內(nèi)容互轉(zhuǎn)工具詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • golang中如何使用kafka方法實(shí)例探究

    golang中如何使用kafka方法實(shí)例探究

    Kafka是一種備受歡迎的流處理平臺,具備分布式、可擴(kuò)展、高性能和可靠的特點(diǎn),在處理Kafka數(shù)據(jù)時(shí),有多種最佳實(shí)踐可用來確保高效和可靠的處理,這篇文章將介紹golang中如何使用kafka方法
    2024-01-01
  • 淺析如何利用Go的plugin機(jī)制實(shí)現(xiàn)熱更新

    淺析如何利用Go的plugin機(jī)制實(shí)現(xiàn)熱更新

    熱更新,或稱熱重載或動態(tài)更新,是一種軟件更新技術(shù),允許程序在運(yùn)行時(shí),不停機(jī)更新代碼或資源,本文主要來討論下GO語言是否可以利用plugin機(jī)制實(shí)現(xiàn)熱更新,感興趣的可以了解下
    2024-04-04
  • Golang如何調(diào)用windows下的dll動態(tài)庫中的函數(shù)

    Golang如何調(diào)用windows下的dll動態(tài)庫中的函數(shù)

    這篇文章主要介紹了Golang如何調(diào)用windows下的dll動態(tài)庫中的函數(shù)方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05

最新評論

永康市| 贡觉县| 白河县| 河源市| 三穗县| 齐河县| 察哈| 伊宁县| 义马市| 容城县| 睢宁县| 沭阳县| 沁阳市| 平顺县| 长泰县| 马山县| 石嘴山市| 安庆市| 西贡区| 青州市| 花莲市| 平邑县| 乌苏市| 宾阳县| 丰台区| 大方县| 枣强县| 天水市| 常德市| 历史| 额敏县| 遂昌县| 新疆| 扎鲁特旗| 临湘市| 屯留县| 贡嘎县| 章丘市| 耿马| 民县| 青州市|