<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在 Go 語言中,struct 是一種常見的資料型別,它可以用來表示複雜的資料結構。在 struct 中,我們可以定義多個欄位,每個欄位可以有不同的型別和名稱。
除了這些基本資訊之外,Go 還提供了 struct tags,它可以用來指定 struct 中每個欄位的元資訊。
在本文中,我們將探討為什麼 Go 語言中需要使用 struct tags,以及 struct tags 的使用場景和優勢。
struct tags 使用還是很廣泛的,特別是在 json 序列化,或者是資料庫 ORM 對映方面。
在定義上,它以 key:value
的形式出現,跟在 struct 欄位後面,除此之外,還有以下幾點需要注意:
在宣告 struct tag 時,使用反引號 `
包圍 tag 的值,可以防止跳脫字元的影響,使 tag 更容易讀取和理解。例如:
type User struct { ID int `json:"id" db:"id"` Name string `json:"name" db:"name"` Email string `json:"email" db:"email"` }
在 struct tag 中,應該避免使用空格,特別是在 tag 名稱和 tag 值之間。使用空格可能會導致編碼或解碼錯誤,並使程式碼更難以維護。例如:
// 不規範的寫法 type User struct { ID int `json: "id" db: "id"` Name string `json: "name" db: "name"` Email string `json: "email" db: "email"` } // 規範的寫法 type User struct { ID int `json:"id" db:"id"` Name string `json:"name" db:"name"` Email string `json:"email" db:"email"` }
在 struct 中,應該避免重複使用同一個 tag 名稱。如果重複使用同一個 tag 名稱,編譯器可能會無法識別 tag,從而導致編碼或解碼錯誤。例如:
// 不規範的寫法 type User struct { ID int `json:"id" db:"id"` Name string `json:"name" db:"name"` Email string `json:"email" db:"name"` } // 規範的寫法 type User struct { ID int `json:"id" db:"id"` Name string `json:"name" db:"name"` Email string `json:"email" db:"email"` }
為了使 struct tag 更加標準化和易於維護,應該使用一些標準化的 tag 名稱。
例如,對於序列化和反序列化,可以使用 json
、xml
、yaml
等;對於資料庫操作,可以使用 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
欄位後面的 -
表示忽略該欄位,也就是說該欄位不會被序列化或反序列化。
如果一個欄位需要指定多個 tag 值,可以使用 ,
將多個 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
表示如果該欄位值為空,則不序列化該欄位。
Go 的反射庫提供了一些方法,可以讓我們在程式執行時獲取和解析結構體標籤。
介紹這些方法之前,先來看看 reflect.StructField
,它是描述結構體欄位的資料型別。定義如下:
type StructField struct { Name string // 欄位名 Type Type // 欄位型別 Tag StructTag // 欄位標籤 }
結構體中還有一些其他欄位,被我省略了,只保留了和本文相關的。
在結構體的反射中,我們經常使用 reflect.TypeOf
獲取型別資訊,然後使用 Type.Field
或 Type.FieldByName()
獲取結構體欄位的 reflect.StructField
,然後根據 StructField
中的資訊做進一步處理。
例如,可以通過 StructField.Tag.Get
方法獲取結構體欄位的標籤值。
下面看一段程式碼:
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) }
執行以上程式碼,輸出結果如下:
Field 'User' exists: User {string int}
User.Name tag: "name"
使用 struct tag 的主要優勢之一是可以在執行時通過反射來存取和操作 struct 中的欄位。
比如在 Go Web 開發中,常常需要將 HTTP 請求中的引數繫結到一個 struct 中。這時,我們可以使用 struct tag 指定每個欄位對應的引數名稱、驗證規則等資訊。在接收到 HTTP 請求時,就可以使用反射機制讀取這些資訊,並根據資訊來驗證引數是否合法。
另外,在將 struct 序列化為 JSON 或者其他格式時,我們也可以使用 struct tag 來指定每個欄位在序列化時的名稱和規則。
此外,使用 struct tag 還可以提高程式碼的可讀性和可維護性。在一個大型的專案中,struct 中的欄位通常會包含很多不同的元資訊,比如資料庫中的表名、欄位名、索引、驗證規則等等。
如果沒有 struct tag,我們可能需要將這些元資訊放在註釋中或者在程式碼中進行寫死。這樣會讓程式碼變得難以維護和修改。而使用 struct tag 可以將這些元資訊與 struct 欄位緊密關聯起來,使程式碼更加清晰和易於維護。
在 Go 的官方 wiki 中,有一個常用的 struct tags 的庫的列表,我複製在下面了,感興趣的同學可以看看原始碼,再繼續深入學習。
以上就是本文的全部內容,如果覺得還不錯的話歡迎點贊,轉發和關注,感謝支援。
參考文章:
https://github.com/golang/go/wiki/Well-known-struct-tags
到此這篇關於為什麼 Go 語言 struct 要使用 tags的文章就介紹到這了,更多相關Go 語言 struct 要使用 tags內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45