回答

收藏

Go 中标签的用途是什么?

技术问答 技术问答 253 人阅读 | 0 人回复 | 2023-09-12

在Go Language Specification 中,它提到了标签的简要概述:- i1 G! [4 j. i( f& w( b% L( k" m; p
字段声明后,可以用可选字符串标记,成为相应字段声明中所有字段的属性。标签可以通过反射界面看到,但会被忽略。
) ~* V: B9 L8 a0 k+ Q$ r. E  r+ v& bgolang// 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"}7 h" I8 `7 C  u" l% q" _% R# K- N# C
这是 IMO 的一个非常简短的解释,我想知道是否有人能给我提供这些标签?# _: t3 _: V2 S# T
                                                               
! b& r0 ~1 g9 W7 U4 T: j' Y    解决方案:                                                               
! w  q: _7 X& J$ z9 V                                                                字段标签允许您将元信息添加到可以通过反射获得的字段中。它通常用于提供转换信息,如何将结构字段编码为另一个格式或从另一个格式解码(或从数据库中存储/检索),但您可以使用它来存储您想要的任何元信息,或用于另一个包装或供您自己使用。
& D. t" r/ |1 a( v/ o& a0 j正如在 文档中提到的reflect.StructTag,按照惯例,标签字符串的值是空格分隔的key:"value"例如:* z6 F, Y- G7 `* p( |8 B
    type User struct    Name string `json:"name" xml:"name"`}
    9 g6 m  {! j* e7 |
的key通常表示包,随后的"value"是,例如json处理/使用密钥encoding/json包。, Y; B- Q8 K' L: C
如果要在 中传递多个信息"value",通常用逗号 ( ,
& r3 k9 v+ i, h
    Name string `json:"name,omitempty" xml:"name"`' k! C) r* h1 P
通常是破折号 -')"value"表示从过程中排除字段的方法(例如,如果json意思是不编组或解组字段)。2 P# Q( \+ l4 H5 _* Z+ X$ t# U/ ~
使用反射访问自定义标签的示例我们可以使用反射(reflect访问结构体字段的标签值。基本上,我们需要获得Type 我们的结构,然后我们可以查询字段,比如Type.Field(i int)或Type.FieldByName(name string)。返回一种方法StructField描述/代表结构域的值;并且StructField.Tag StructTag] 6型值,描述 / 代表标签值。/ K2 Q- v+ b* M: m; p! X1 m- f# \
我们以前谈过“约定”。如果你遵循这个公约,你可以使用它StructTag.Get(key string)它分析变量值,并返回该方法"value"的key指定。该约定已实现/内置到此Get()方法。如果你不遵守协议,Get()无法分析key:"value"找到你想找到的东西。这不是问题,但你需要实现你的分析逻辑。
4 Y' t5 H9 p9 w: ^# H/ O  w" w还有StructTag.Lookup()(在 Go 1.7 添加)它是“类似于Get()但将不包含给定键的标签与与给定键相关的空字符串标签区分开来。。; H3 [  x- g9 y8 `
让我们看一个简单的例子:
+ x! |! D! w3 g% d* c5 n
    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"))}/ K4 s/ x4 i! m' t
输出(在Go Playground上试试):
& @" P- P( t( n# M3 P
    Field: User.Name    Whole tag value : "mytag:"MyName""    Value of 'mytag': "MyName"Field: User.Email    Whole tag value : "mytag:"MyEmail""    Value of 'mytag': "MyEmail"* \+ D& O$ M( y7 s0 b
GopherCon 2015 有一个关于结构标签的演示,称为:
+ W+ E' r3 g' S2 Q" W多面性(幻灯片)结构标签(和视频)( m) ]0 z4 Q- l# u# d/ I% C1 }+ ^
以下是常用标签键列表:json- 由encoding/json使用包包,详见json.Marshal()2 e$ L) v2 j- a& q; E% E. F
xml- 由encoding/xml使用包包,详见xml.Marshal()
; T: j/ ^% k7 S- ubson- 由gobson 使用,详见bson.Marshal(); 也由mongo-go在bson package doc 有详细说明/ K, |1 w  z5 E7 n$ D' T9 f: m
protobuf-github.com/golang/protobuf/proto用户在包文档中有详细说明
. [" e  G8 U; C- G! u& T1 Syaml- 由gopkg.in/yaml.v使用2包,详见yaml.Marshal()
; o6 l8 {' k5 N) i5 \db- 由github.com/jmoiron/sqlx使用包;也被github.com/go-gorp/gorp包使用
  n, {8 M% a- u5 N' S- Q# q+ sorm- 由github.com/astaxie/beego/orm包使用,详细见模型 – Beego ORM8 D& |6 [8 F- v5 E+ F
gorm- 使用gorm.io/gorm,在他们的文档中可以找到示例
& T) D. _7 [1 _4 tvalid- 由github.com/asaskevich/govalidator在项目页面上可以找到包使用的示例
8 L1 \( j) ]! z8 I* Z1 p% vdatastore- 由appengine/datastore(Google App Engine 平台、Datastore 服务)使用,详见属性7 f: |/ i# A: z! X7 J* F( M+ I
schema- 用于github.com/gorilla/schema填充structHTML 表单值在包文档中有详细说明5 N' J% S4 h+ _0 S" C  b
asn- 由encoding/asn一包使用,详见asn1.Marshal()和asn1.Unmarshal()
. s) i. J7 v- D/ [9 N9 Icsv- 由github.com/gocarina/gocsv包使用
- J7 a1 K0 F! ~! r6 Oenv- 由github.com/caarlos0/env包使用
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则