问题
结构题字段声明后面可以跟一个可选的字符串文字标签,该标签成为相应字段声明中所有字段的属性。这些标签通过反射接口可见,但在其他情况下会被忽略。那么它的作用是什么呢?
// A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers.
struct {
microsec uint64 "field 1"
serverIP6 uint64 "field 2"
process string "field 3"
}
解答
字段的标签允许您将元信息附加到可以使用反射获取的字段。通常它用于提供有关如何将结构体字段编码为另一种格式或从另一种格式解码(或从数据库存储/检索)的转换信息,但您可以使用它来存储您想要的任何元信息,无论是用于另一种格式打包或供您自己使用。标记字符串的值是一个以空格分隔的对列表key:"value"
,例如:
type User struct {
Name string `json:"name" xml:"name"`
}
通常key
表示后续的包"value"
,例如json
密钥由包处理/使用encoding/json。
如果要在 中传递多个信息"value"
,通常用逗号(','
)分隔来指定,例如
Name string `json:"name,omitempty" xml:"name"`
使用反射访问自定义标签的示例
我们可以使用反射(reflect包)来访问结构体字段的标签值。基本上我们需要获取Type结构体的 ,然后我们可以使用Type.Field(i int)
or查询字段Type.FieldByName(name string)
。这些方法返回一个StructField描述/表示结构体字段的值;并且是描述/表示标签值StructField.Tag
的类型的值。StructTag
前面我们谈到了“约定”。此约定意味着,如果您遵循它,您可以使用StructTag.Get(key string)解析标记值并返回您指定"value"
的值的方法key
。该约定被实现/内置到该Get()
方法中。如果您不遵循约定,Get()
将无法解析key:"value"
对并找到您要查找的内容。这也不是问题,但是您需要实现自己的解析逻辑。
还有StructTag.Lookup()(在 Go 1.7 中添加)“类似于Get()
但区分不包含给定键的标签和将空字符串与给定键相关联的标签”。
让我们看一个简单的例子:
type User struct {
Name string `mytag:"MyName"`
Email string `mytag:"MyEmail"`
}
u := User{"Bob", "bob@mycompany.com"}
t := reflect.TypeOf(u)
for _, fieldName := range []string{"Name", "Email"} {
field, found := t.FieldByName(fieldName)
if !found {
continue
}
fmt.Printf("\nField: User.%s\n", fieldName)
fmt.Printf("\tWhole tag value : %q\n", field.Tag)
fmt.Printf("\tValue of 'mytag': %q\n", field.Tag.Get("mytag"))
}
输出:
Field: User.Name
Whole tag value : "mytag:\"MyName\""
Value of 'mytag': "MyName"
Field: User.Email
Whole tag value : "mytag:\"MyEmail\""
Value of 'mytag': "MyEmail"
以下是常用标签键的列表:
json
- 由包使用encoding/json,详细信息在json.Marshal()xml
- 由包使用encoding/xml,详细信息在xml.Marshal()bson
- 由gobson使用,详细信息在bson.Marshal();也由mongo-go驱动程序提供,详细信息请参见bson 包文档protobuf
- 由 所使用github.com/golang/protobuf/proto,详细信息请参见软件包文档yaml
- 由包使用gopkg.in/yaml.v2,详细信息在yaml.Marshal()db
- 被包使用github.com/jmoiron/sqlx;也被github.com/go-gorp/gorp包使用orm
- 包使用github.com/astaxie/beego/orm,详细信息见模型 – Beego ORMgorm
- 使用者gorm.io/gorm,示例可以在他们的文档中找到valid
- 包使用github.com/asaskevich/govalidator,示例可以在项目页面找到datastore
appengine/datastore- 由(Google App Engine 平台、数据存储服务)使用,详细信息请参见属性schema
- 用于github.com/gorilla/schema填充struct
HTML 表单值,详细信息请参见包文档asn1
- 由包使用encoding/asn1,详细信息在asn1.Marshal()和asn1.Unmarshal()csv
github.com/gocarina/gocsv- 由包使用env
github.com/caarlos0/env- 由包使用