Go的标签有什么用途? [英] What are the use(s) for tags in Go?
问题描述
在 Go语言规范中,它提到了标签的简要概述:
字段声明后面可以跟随一个可选的字符串字面标记
,它成为相应
中所有字段的属性现场声明。通过反射
接口使标签变为可见,但忽略它们。//一个对应于TimeStamp的结构协议缓冲区。
//标记字符串定义协议缓冲区字段号。
struct {
microsec uint64field 1
serverIP6 uint64field 2
process stringfield 3
}
这是IMO的一个非常简短的解释,我想知道是否有人可以向我提供使用这些标签的内容会是?
字段的标记允许您将元信息附加到可以使用反射获取的字段。通常它用于提供有关结构字段如何被编码为或从另一种格式解码(或从数据库中存储/检索)的转换信息,但是您可以使用它来存储您想要的任何元信息,或者用于另一个包或为自己使用。
正如 reflect.StructTag
,按照惯例,标记字符串的值是以空格分隔的键:value
对,例如:
类型用户结构{
名称字符串`json:name xml:name`
}
value
用于的包,例如 json
键是由 编码/ json
包。
如果要传递多个信息value
,通常用逗号分隔(','
),例如
名称字符串`json:name,omitemptyxml:name`
pre>
通常为
value的破折号值(
意味着从过程中排除该字段(例如,在' - '
)json
的情况下,这意味着不对这个字段进行编组或解组)。
使用访问自定义标签的示例我们可以使用反射(
反映
包)来访问struct字段的标记值。基本上我们需要获得类型
我们的结构,然后我们可以查询字段如与Type.Field(i int)
或Type.FieldByName(name string)
。这些方法返回值为StructField
其描述/表示结构字段;和StructField.Tag
是一个 <$
以前我们谈过关于convention的内容
, / em>的。这个惯例意味着如果你遵循它,你可以使用StructTag StructTag.Get (key string)
方法,该方法解析标签的值并返回的
您指定。 约定被实现/构建到值
>键Get()
方法中。如果你不遵守约定,Get()
将不能解析键:value
对并找到你要找的东西。这也不是问题,但是你需要实现自己的解析逻辑。
还有
StructTag.Lookup()
(在Go 1.7中添加) code> Get(),但区分不包含给定键的标签与将空字符串与给定键相关联的标签。
$
类型User struct {
名称字符串`mytag: MyName`
电子邮件字符串`mytag:MyEmail`
}
u:=用户{Bob,bob@mycompany.com}
t := reflect.TypeOf(u)
for _,fieldName:= range [] string {Name,Email} {
field,found:= t.FieldByName(fieldName )
if!found {
continue
}
fmt.Printf(\\\
Field:User。%s\\\
,fieldName)
fmt.Printf (\Whole标签值:%q \ n,field.Tag)
fmt.Printf(\tV 'mytag':%q\\\
,field.Tag.Get(mytag))
}
输出(在 Go Playground 上试用):
字段:User.Name
整个标记值:mytag:\MyName\
值'mytag':MyName
字段:User.Email
整个标记值:mytag:\MyEmail\
'mytag'的值: MyEmail
GopherCon 2015有关于struct标签叫:
这里是一个常用的标签键列表:
-
json
- 由encoding / json
包,详见json.Marshal()
-
xml
- 由encoding / xml
使用包,详见xml.Marshal()
-
bson
- 由 gobson ,详见bson。 Marshal()
-
protobuf
- 由github.com/golang/protobuf/proto
,详细介绍包文档 -
yaml
- 由gopkg.in/yaml.v2
包,详细信息请参见yaml.Marshal()
-
db
- used通过github.com/jmoiron/sqlx
包;也用于github.com/go-gorp/gorp
-
orm
- 由github.com/astaxie/beego/orm
软件包,在 Models - Beego ORM -
gorm
code> - 由 -
有效
- 由github.com/asaskevich/govalidator
包,可以在项目页面找到示例 -
数据存储
- 由 rel =noreferrer>appengine / datastore
href =https://cloud.google.com/appengine/docs/go/datastore/reference#hdr-Properties =noreferrer>属性 -
schema
- 由使用github .com / gorilla / schema
来填充struct
与HTML表单值,详情请参阅包文档 -
asn
- 由encoding / asn1
包,详细信息请参见asn1.Marshal()
和asn1.Unmarshal()
-
csv
- 由github.com/gocarina/gocsv
礼包
github.com/jinzhu/gorm $ c $使用c>
包,可以在他们的文档中找到示例:模型 In the Go Language Specification, it mentions a brief overview of tags:
A field declaration may be followed by an optional string literal tag, which becomes an attribute for all the fields in the corresponding field declaration. The tags are made visible through a reflection interface but are otherwise ignored.
// 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" }
This is a very short explanation IMO, and I was wondering if anyone could provide me with what use these tags would be?
A tag for a field allows you to attach meta-information to the field which can be acquired using reflection. Usually it is used to provide transformation info on how a struct field is encoded to or decoded from another format (or stored/retrieved from a database), but you can use it to store whatever meta-info you want to, either intended for another package or for your own use.
As mentioned in the documentation of reflect.StructTag
, by convention the value of a tag string is a space-separated key:"value"
pairs, for example:
type User struct {
Name string `json:"name" xml:"name"`
}
The key
usually denotes the package that the subsequent "value"
is for, for example json
keys are processed/used by the encoding/json
package.
If multiple information is to be passed in the "value"
, usually it is specified by separating it with a comma (','
), e.g.
Name string `json:"name,omitempty" xml:"name"`
Usually a dash value ('-'
) for the "value"
means to exclude the field from the process (e.g. in case of json
it means not to marshal or unmarshal that field).
Example of accessing your custom tags using reflection
We can use reflection (reflect
package) to access the tag values of struct fields. Basically we need to acquire the Type
of our struct, and then we can query fields e.g. with Type.Field(i int)
or Type.FieldByName(name string)
. These methods return a value of StructField
which describe / represent a struct field; and StructField.Tag
is a value of type StructTag
which describes / represents a tag value.
Previously we talked about "convention". This convention means that if you follow it, you may use the StructTag.Get(key string)
method which parses the value of a tag and returns you the "value"
of the key
you specify. The convention is implemented / built into this Get()
method. If you don't follow the convention, Get()
will not be able to parse key:"value"
pairs and find what you're looking for. That's also not a problem, but then you need to implement your own parsing logic.
Also there is StructTag.Lookup()
(was added in Go 1.7) which is "like Get()
but distinguishes the tag not containing the given key from the tag associating an empty string with the given key".
So let's see a simple example:
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"))
}
Output (try it on the Go Playground):
Field: User.Name
Whole tag value : "mytag:\"MyName\""
Value of 'mytag': "MyName"
Field: User.Email
Whole tag value : "mytag:\"MyEmail\""
Value of 'mytag': "MyEmail"
GopherCon 2015 had a presentation about struct tags called:
The Many Faces of Struct Tags (slide) (and a video)
Here is a list of commonly used tag keys:
json
- used by theencoding/json
package, detailed atjson.Marshal()
xml
- used by theencoding/xml
package, detailed atxml.Marshal()
bson
- used by gobson, detailed atbson.Marshal()
protobuf
- used bygithub.com/golang/protobuf/proto
, detailed in the package docyaml
- used by thegopkg.in/yaml.v2
package, detailed atyaml.Marshal()
db
- used by thegithub.com/jmoiron/sqlx
package; also used bygithub.com/go-gorp/gorp
packageorm
- used by thegithub.com/astaxie/beego/orm
package, detailed at Models – Beego ORMgorm
- used by thegithub.com/jinzhu/gorm
package, examples can be found in their doc: Modelsvalid
- used by thegithub.com/asaskevich/govalidator
package, examples can be found in the project pagedatastore
- used byappengine/datastore
(Google App Engine platform, Datastore service), detailed at Propertiesschema
- used bygithub.com/gorilla/schema
to fill astruct
with HTML form values, detailed in the package docasn
- used by theencoding/asn1
package, detailed atasn1.Marshal()
andasn1.Unmarshal()
csv
- used by thegithub.com/gocarina/gocsv
package
这篇关于Go的标签有什么用途?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!