激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - Go 語言中結構體打 Tag 是什么意思?

Go 語言中結構體打 Tag 是什么意思?

2021-11-15 22:19Golang夢工廠AsongGo Golang

哈嘍,大家好,我是asong。今天想與大家分享Go語言中結構體標簽是怎么使用的,以及怎樣定制自己的結構體標簽解析。

Go 語言中結構體打 Tag 是什么意思?

前言

哈嘍,大家好,我是asong。今天想與大家分享Go語言中結構體標簽是怎么使用的,以及怎樣定制自己的結構體標簽解析。

大多數初學者在看公司的項目代碼時,看到的一些結構體定義會是這樣的:

  1. type Location struct {
  2. Longitude float32 `json:"lon,omitempty"`
  3. Latitude float32 `json:"lat,omitempty"`
  4. }

字段后面會有一個標簽,這個標簽有什么用呢?

上面的例子中,標簽json:"lon,omitempty"代表的意思是結構體字段的值編碼為json對象時,每一個導出字段變成該對象的一個成員,這個成員的名字為lon或者lat,并且當字段是空值時,不導出該字段;總結就是lon、lat是重命名成員的名字,omitempty用來決定成員是否導出。

看到這里,有一些朋友可能會好奇,這個你是怎么知道這樣使用的呢?我可以隨便寫標簽嗎?

接下來我們就一點點來揭秘,開車!!!

什么是標簽

Go語言提供了可通過反射發現的的結構體標簽,這些在標準庫json/xml中得到了廣泛的使用,orm框架也支持了結構體標簽,上面那個例子的使用就是因為encoding/json支持了結構體標簽,不過他有自己的標簽規則;但是他們都有一個總體規則,這個規則是不能更改的,具體格式如下:

  1. `key1:"value1" key2:"value2" key3:"value3"...` // 鍵值對用空格分隔

結構體標簽可以有多個鍵值對,鍵與值要用冒號分隔,值要使用雙引號括起來,多個鍵值對之間要使用一個空格分隔,千萬不要使用逗號!!!

如果我們想要在一個值中傳遞多個信息怎么辦?不同庫中實現的是不一樣的,在encoding/json中,多值使用逗號分隔:

  1. `json:"lon,omitempty"`

在gorm中,多值使用分號分隔:

  1. `gorm:"column:id;primaryKey"

具體使用什么符號分隔需要大家要看各自庫的文檔獲取。

結構體標簽是在編譯階段就和成員進行關聯的,以字符串的形式進行關聯,在運行階段可以通過反射讀取出來。

現在大家已經知道什么是結構體標簽了,規則還是很規范的,但是很容易出錯,因為Go語言在編譯階段并不會對其格式做合法鍵值對的檢查,這樣我們不小心寫錯了,就很難被發現,不過我們有go vet工具做檢查,具體使用來看一個例子:

  1. type User struct {
  2. Name string `abc def ghk`
  3. Age uint16 `123: 232`
  4. }
  5. func main() {
  6. }

然后執行go vet main.go,得出執行結果:

  1. # command-line-arguments
  2. go_vet_tag/main.go:4:2: struct field tag `abc def ghk` not compatible with reflect.StructTag.Get: bad syntax for struct tag pair
  3. go_vet_tag/main.go:5:2: struct field tag `123: 232` not compatible with reflect.StructTag.Get: bad syntax for struct tag value

bad syntax for struct tag pair告訴我們鍵值對語法錯誤,bad syntax for struct tag value值語法錯誤。

所以在我們項目中引入go vet作為CI檢查是很有必要的。

標簽使用場景

Go官方已經幫忙整理了哪些庫已經支持了struct tag:https://github.com/golang/go/wiki/Well-known-struct-tags。

Tag Documentation
xml https://godoc.org/encoding/xml
json https://godoc.org/encoding/json
asn1 https://godoc.org/encoding/asn1
reform https://godoc.org/gopkg.in/reform.v1
dynamodb https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/#Marshal
bigquery https://godoc.org/cloud.google.com/go/bigquery
datastore https://godoc.org/cloud.google.com/go/datastore
spanner https://godoc.org/cloud.google.com/go/spanner
bson https://godoc.org/labix.org/v2/mgo/bson, https://godoc.org/go.mongodb.org/mongo-driver/bson/bsoncodec
gorm https://godoc.org/github.com/jinzhu/gorm
yaml https://godoc.org/gopkg.in/yaml.v2
toml https://godoc.org/github.com/pelletier/go-toml
validate https://github.com/go-playground/validator
mapstructure https://godoc.org/github.com/mitchellh/mapstructure
parser https://godoc.org/github.com/alecthomas/participle
protobuf https://github.com/golang/protobuf
db https://github.com/jmoiron/sqlx
url https://github.com/google/go-querystring
feature https://github.com/nikolaydubina/go-featureprocessing

像json、yaml、gorm、validate、mapstructure、protobuf這幾個庫的結構體標簽是很常用的,gin框架就集成了validate庫用來做參數校驗,方便了許多,之前寫了一篇關于validate的文章:boss: 這小子還不會使用validator庫進行數據校驗,開了~~~,可以關注一下。

具體這些庫中是怎么使用的,大家可以看官方文檔介紹,寫的都很詳細,具體場景具體使用哈!!!

自定義結構體標簽

現在我們可以回答開頭的一個問題了,結構體標簽是可以隨意寫的,只要符合語法規則,任意寫都可以的,但是一些庫沒有支持該標簽的情況下,隨意寫的標簽是沒有任何意義的,如果想要我們的標簽變得有意義,就需要我們提供解析方法。可以通過反射的方式獲取標簽,所以我們就來看一個例子,如何使用反射獲取到自定義的結構體標簽。

  1. type User struct {
  2. Name string `asong:"Username"`
  3. Age uint16 `asong:"age"`
  4. Password string `asong:"min=6,max=10"`
  5. }
  6. func getTag(u User) {
  7. t := reflect.TypeOf(u)
  8. for i := 0; i < t.NumField(); i++ {
  9. field := t.Field(i)
  10. tag := field.Tag.Get("asong")
  11. fmt.Println("get tag is ", tag)
  12. }
  13. }
  14. func main() {
  15. u := User{
  16. Name: "asong",
  17. Age: 5,
  18. Password: "123456",
  19. }
  20. getTag(u)
  21. }

運行結果如下:

  1. get tag is Username
  2. get tag is age
  3. get tag is min=6,max=10

這里我們使用TypeOf方法獲取的結構體類型,然后去遍歷字段,每個字段StructField都有成員變量Tag:

  1. // A StructField describes a single field in a struct.
  2. type StructField struct {
  3. Name string
  4. PkgPath string
  5. Type Type // field type
  6. Tag StructTag // field tag string
  7. Offset uintptr // offset within struct, in bytes
  8. Index []int // index sequence for Type.FieldByIndex
  9. Anonymous bool // is an embedded field
  10. }

Tag是一個內置類型,提供了Get、Loopup兩種方法來解析標簽中的值并返回指定鍵的值:

  1. func (tag StructTag) Get(key string) string
  2. func (tag StructTag) Lookup(key string) (value string, ok bool)

Get內部也是調用的Lookup方法。區別在于Lookup會通過返回值告知給定key是否存在與標簽中,Get方法完全忽略了這個判斷。

總結

本文主要介紹一下Go語言中的結構體標簽是什么,以及如何使用反射獲取到解結構體標簽,在日常開發中我們更多的是使用一些庫提供好的標簽,很少自己開發使用,不過大家有興趣的話可以讀一下validae的源碼,看看他是如何解析結構體中的tag,也可以自己動手實現一個校驗庫,當作練手項目。

文中代碼已上傳github:https://github.com/asong2020/Golang_Dream/tree/master/code_demo/struct_tag_demo

原文鏈接:https://mp.weixin.qq.com/s/3sz8oE8nGmba8WECXa0AWg

延伸 · 閱讀

精彩推薦
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
主站蜘蛛池模板: 中午字幕无线码一区2020 | 欧美亚洲啪啪 | www.99热精品| 2021免费日韩视频网 | 欧美久久久一区二区三区 | 九草在线 | 亚洲免费在线视频 | 欧美xxxxx视频 | 国产精品视频yy9299一区 | 欧美精品一级 | 国产视频在线观看免费 | 成人毛片一区 | 欧美三级美国一级 | 久久久久久久久久久av | 青草av.久久免费一区 | 国产精品午夜在线 | 久久久久久久久久久综合 | 中文字幕综合在线观看 | 国产成人精品免费视频大全最热 | 国产精品一区二区三区在线播放 | 精品一区二区免费 | 狠狠操电影 | 国产精品免费一区二区三区都可以 | 性欧美一区二区三区 | 日本一级黄色毛片 | 人人舔人人射 | 午夜丰满少妇高清毛片1000部 | 亚洲片在线观看 | 羞羞视频免费入口网站 | 欧美日韩a∨毛片一区 | 久久久久久久久免费 | 日韩视频高清 | 精精国产xxxx视频在线野外 | 国产精品视频在线观看免费 | 香蕉国产9 | 成人国产精品一区 | 色污视频| 曰本三级日本三级日本三级 | 国产一区二区三区高清 | 竹内纱里奈55在线观看 | 天天草天天干天天射 |