Go 中如何使用结构体标签
译者:baiyutang
原文:https://www.digitalocean.com/community/tutorials/how-to-use-struct-tags-in-go
介绍
结构体,被用于搜集多个信息片段到一起集合到一个单元。这些信息集合被用于描述较高层级概念,如 Address
,由 Street
、City
、State
和 PostalCode
组成。当你从数据库、API 等系统中读取信息时,你可以使用结构体标签控制信息如何给一个结构体的字段赋值。结构体标签是附着在一个结构体字段上的小块元数据,给使用结构体的 Go 代码提供指令。
结构体标签看起来是什么
结构体标签是出现在 Go 结构体类型声明后面的注释,每个标签由短字符关联相应的值组成。
一个结构体标签看起来如下,标签偏移带有反引号 `
符号。
type User struct { Name string `example:"name"` }
然后,其他 Go 代码能够检查这些结构并提取分配给它请求的特定键的值。如果没有其他代码检查,结构标签对代码的操作没有影响。
试试这个例子,看看结构体标签是什么样子的,如果没有来自另一个包的代码,它们将没有效果。
package main import "fmt" type User struct { Name string `example:"name"` } func (u *User) String() string { return fmt.Sprintf("Hi! My name is %s", u.Name) } func main() { u := &User{ Name: "Sammy", } fmt.Println(u) }
它会输出
Output Hi! My name is Sammy
JSON 编码
JavaScript Object Notation (JSON) 是一种文本格式,用于编码以不同字符串键组织的数据集合。它通常用于不同程序之间的数据通信,因为这种格式非常简单,存在许多库可以用许多不同的语言解码它。下面是 JSON 的一个例子:
{ "language": "Go", "mascot": "Gopher" }
试试这个例子,看看 JSON 是如何在没有结构体标签的情况下编码的:
package main import ( "encoding/json" "fmt" "log" "os" "time" ) type User struct { Name string Password string PreferredFish []string CreatedAt time.Time } func main() { u := &User{ Name: "Sammy the Shark", Password: "fisharegreat", CreatedAt: time.Now(), } out, err := json.MarshalIndent(u, "", " ") if err != nil { log.Println(err) os.Exit(1) } fmt.Println(string(out)) }
这会打印如下输出
{ "Name": "Sammy the Shark", "Password": "fisharegreat", "CreatedAt": "2019-09-23T15:50:01.203059-04:00" }
package main import ( "encoding/json" "fmt" "log" "os" "time" ) type User struct { name string password string preferredFish []string createdAt time.Time } func main() { u := &User{ name: "Sammy the Shark", password: "fisharegreat", createdAt: time.Now(), } out, err := json.MarshalIndent(u, "", " ") if err != nil { log.Println(err) os.Exit(1) } fmt.Println(string(out)) }
使用结构体标签控制编码
package main import ( "encoding/json" "fmt" "log" "os" "time" ) type User struct { Name string `json:"name"` Password string `json:"password"` PreferredFish []string `json:"preferredFish"` CreatedAt time.Time `json:"createdAt"` } func main() { u := &User{ Name: "Sammy the Shark", Password: "fisharegreat", CreatedAt: time.Now(), } out, err := json.MarshalIndent(u, "", " ") if err != nil { log.Println(err) os.Exit(1) } fmt.Println(string(out)) }
这会输出
{ "name": "Sammy the Shark", "password": "fisharegreat", "preferredFish": null, "createdAt": "2019-09-23T18:16:17.57739-04:00" }
移出结构体空字段
package main import ( "encoding/json" "fmt" "log" "os" "time" ) type User struct { Name string `json:"name"` Password string `json:"password"` PreferredFish []string `json:"preferredFish,omitempty"` CreatedAt time.Time `json:"createdAt"` } func main() { u := &User{ Name: "Sammy the Shark", Password: "fisharegreat", CreatedAt: time.Now(), } out, err := json.MarshalIndent(u, "", " ") if err != nil { log.Println(err) os.Exit(1) } fmt.Println(string(out)) }
这个例子将输出
{ "name": "Sammy the Shark", "password": "fisharegreat", "createdAt": "2019-09-23T18:21:53.863846-04:00" }
忽略私有字段
package main import ( "encoding/json" "fmt" "log" "os" "time" ) type User struct { Name string `json:"name"` Password string `json:"-"` CreatedAt time.Time `json:"createdAt"` } func main() { u := &User{ Name: "Sammy the Shark", Password: "fisharegreat", CreatedAt: time.Now(), } out, err := json.MarshalIndent(u, "", " ") if err != nil { log.Println(err) os.Exit(1) } fmt.Println(string(out)) }
当你运营这个例子,你将看到这个输出:
{ "name": "Sammy the Shark", "createdAt": "2019-09-23T16:08:21.124481-04:00" }
总结
结构体标签提供一种强大的方法,增大结构体作用的代码功能。很多标准库和第三方库通过结构体标签来提供方式定制操作。在代码中有效地使用它们不仅提供了这种定制行为,还简洁地记录了将来的开发人员如何使用这些字段。
本文文字及图片出自 InfoQ
你也许感兴趣的:
- 【外评】电脑从哪里获取时间?
- 【外评】为什么 Stack Overflow 正在消失?
- Android 全力押注 Rust,Linux 却在原地踏步?谷歌:用 Rust 重写固件太简单了!
- 【外评】哪些开源项目被广泛使用,但仅由少数人维护?
- 【外评】好的重构与不好的重构
- C 语言老将从中作梗,Rust for Linux 项目内讧升级!核心维护者愤然离职:不受尊重、热情被消耗光
- 【外评】代码审查反模式
- 我受够了维护 AI 生成的代码
- 【外评】Linux 桌面市场份额升至 4.45
- 【外评】作为全栈开发人员如何跟上 AI/ML 的发展?
你对本文的反应是: