回答

收藏

Go 中标签的用途是什么?

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

在Go Language Specification 中,它提到了标签的简要概述:" ?8 h; m5 ~( M
字段声明后,可以用可选字符串标记,成为相应字段声明中所有字段的属性。标签可以通过反射界面看到,但会被忽略。
' \; ]5 M' ~/ R3 k  D1 p$ t* _golang// 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"}! K& @2 k0 s7 Y: v0 }" M" g$ |
这是 IMO 的一个非常简短的解释,我想知道是否有人能给我提供这些标签?
; C) f$ N" ^! Z% E; `- P' c; O                                                               
# m+ I5 G7 r4 [" \0 D    解决方案:                                                                0 |" ~$ m( p- f* {0 D
                                                                字段标签允许您将元信息添加到可以通过反射获得的字段中。它通常用于提供转换信息,如何将结构字段编码为另一个格式或从另一个格式解码(或从数据库中存储/检索),但您可以使用它来存储您想要的任何元信息,或用于另一个包装或供您自己使用。
$ M* n3 p* J: p0 o. L7 n9 D/ ^正如在 文档中提到的reflect.StructTag,按照惯例,标签字符串的值是空格分隔的key:"value"例如:. U. S4 N" |8 m2 W) o8 `! S
    type User struct    Name string `json:"name" xml:"name"`}
    ; ?/ I# J0 `* @
的key通常表示包,随后的"value"是,例如json处理/使用密钥encoding/json包。
: ?3 L7 I' Y& h如果要在 中传递多个信息"value",通常用逗号 ( ,+ a% B1 C) @" S" K$ E7 G+ r
    Name string `json:"name,omitempty" xml:"name"`, g. d1 l% S1 R9 `0 T, r
通常是破折号 -')"value"表示从过程中排除字段的方法(例如,如果json意思是不编组或解组字段)。
5 O7 |, z! T2 f' x5 z8 C使用反射访问自定义标签的示例我们可以使用反射(reflect访问结构体字段的标签值。基本上,我们需要获得Type 我们的结构,然后我们可以查询字段,比如Type.Field(i int)或Type.FieldByName(name string)。返回一种方法StructField描述/代表结构域的值;并且StructField.Tag StructTag] 6型值,描述 / 代表标签值。
3 y  ~) h  F2 d$ I$ A8 E9 V4 d& ~我们以前谈过“约定”。如果你遵循这个公约,你可以使用它StructTag.Get(key string)它分析变量值,并返回该方法"value"的key指定。该约定已实现/内置到此Get()方法。如果你不遵守协议,Get()无法分析key:"value"找到你想找到的东西。这不是问题,但你需要实现你的分析逻辑。  f* s+ _- C3 |- }
还有StructTag.Lookup()(在 Go 1.7 添加)它是“类似于Get()但将不包含给定键的标签与与给定键相关的空字符串标签区分开来。。
/ }) J- V9 l  c, k; \% l' F" C让我们看一个简单的例子:
/ h3 f0 b! e8 [# @
    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"))}* Z* x& t8 Z8 T4 Z  h
输出(在Go Playground上试试):/ a" W+ t: X/ D( [% z
    Field: User.Name    Whole tag value : "mytag:"MyName""    Value of 'mytag': "MyName"Field: User.Email    Whole tag value : "mytag:"MyEmail""    Value of 'mytag': "MyEmail"
    3 R' \/ g2 m9 ~) {. x, C
GopherCon 2015 有一个关于结构标签的演示,称为:
- [" X6 }# j* K" ?2 o& I4 ]8 w7 w多面性(幻灯片)结构标签(和视频)
- g9 t: q0 p! c/ Q+ U( H8 M以下是常用标签键列表:json- 由encoding/json使用包包,详见json.Marshal()
1 h( B; ?; S% n8 @5 V$ G9 Nxml- 由encoding/xml使用包包,详见xml.Marshal()
7 |) ^) W1 w: {0 G1 X" w3 W/ lbson- 由gobson 使用,详见bson.Marshal(); 也由mongo-go在bson package doc 有详细说明
8 }2 E# n8 @6 I1 }% Y- v; @protobuf-github.com/golang/protobuf/proto用户在包文档中有详细说明) _- ~% P9 P  w  `
yaml- 由gopkg.in/yaml.v使用2包,详见yaml.Marshal()
7 g- G7 e! g/ z" x: B$ G* ~db- 由github.com/jmoiron/sqlx使用包;也被github.com/go-gorp/gorp包使用+ A$ {6 m0 i+ l
orm- 由github.com/astaxie/beego/orm包使用,详细见模型 – Beego ORM
% d3 m: e0 F" a- H: A. h' X& lgorm- 使用gorm.io/gorm,在他们的文档中可以找到示例: I- \! |% Z% v3 i; D: q
valid- 由github.com/asaskevich/govalidator在项目页面上可以找到包使用的示例! y; j0 D' P2 V  |% F1 y$ F4 H4 D
datastore- 由appengine/datastore(Google App Engine 平台、Datastore 服务)使用,详见属性4 x: o$ _$ A7 B" j$ v4 J
schema- 用于github.com/gorilla/schema填充structHTML 表单值在包文档中有详细说明& o& l. ?7 N2 F( g8 U& o
asn- 由encoding/asn一包使用,详见asn1.Marshal()和asn1.Unmarshal()3 e/ }) u. H6 `! H, W
csv- 由github.com/gocarina/gocsv包使用
8 m) F; |4 i4 c( \3 ienv- 由github.com/caarlos0/env包使用
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则