回答

收藏

Go 中标签的用途是什么?

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

在Go Language Specification 中,它提到了标签的简要概述:
! R, @& x# Y* v5 I& y4 x- ], }. }字段声明后,可以用可选字符串标记,成为相应字段声明中所有字段的属性。标签可以通过反射界面看到,但会被忽略。
+ H: Y# Q+ q8 c* c) v- ~6 Zgolang// 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"}
) T8 U, `6 K& s
这是 IMO 的一个非常简短的解释,我想知道是否有人能给我提供这些标签?& x& U! ~+ e2 T5 w: @
                                                                3 u  c, |" }9 Z: m) \2 ^4 e" o
    解决方案:                                                               
4 I& s7 ?  H$ o7 [7 H                                                                字段标签允许您将元信息添加到可以通过反射获得的字段中。它通常用于提供转换信息,如何将结构字段编码为另一个格式或从另一个格式解码(或从数据库中存储/检索),但您可以使用它来存储您想要的任何元信息,或用于另一个包装或供您自己使用。
2 o/ l8 D" x9 ^8 h+ ~- g* u* P正如在 文档中提到的reflect.StructTag,按照惯例,标签字符串的值是空格分隔的key:"value"例如:" a  F+ s" U* b. d
    type User struct    Name string `json:"name" xml:"name"`}1 s; s# K+ V! L7 U3 b$ P/ {3 C" A
的key通常表示包,随后的"value"是,例如json处理/使用密钥encoding/json包。
5 X: g. m$ p! W$ O如果要在 中传递多个信息"value",通常用逗号 ( ,: n' W) v$ s1 Y& a
    Name string `json:"name,omitempty" xml:"name"`
    ' q3 h" a: h# L. R% R0 I9 p
通常是破折号 -')"value"表示从过程中排除字段的方法(例如,如果json意思是不编组或解组字段)。, X! X5 U" o7 j: `* a1 [9 H) N
使用反射访问自定义标签的示例我们可以使用反射(reflect访问结构体字段的标签值。基本上,我们需要获得Type 我们的结构,然后我们可以查询字段,比如Type.Field(i int)或Type.FieldByName(name string)。返回一种方法StructField描述/代表结构域的值;并且StructField.Tag StructTag] 6型值,描述 / 代表标签值。% w5 q6 k! a+ Q! O- b2 j; V
我们以前谈过“约定”。如果你遵循这个公约,你可以使用它StructTag.Get(key string)它分析变量值,并返回该方法"value"的key指定。该约定已实现/内置到此Get()方法。如果你不遵守协议,Get()无法分析key:"value"找到你想找到的东西。这不是问题,但你需要实现你的分析逻辑。
. |' K: t  x& M/ K, U/ B8 K还有StructTag.Lookup()(在 Go 1.7 添加)它是“类似于Get()但将不包含给定键的标签与与给定键相关的空字符串标签区分开来。。
% }8 T3 A2 i7 |# }1 b/ J) ~+ V让我们看一个简单的例子:4 K; K# L5 K) D6 Z4 i$ ^! c# d9 X, T
    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"))}  @( x1 S! E: s) b9 c# _3 v, N+ m& P
输出(在Go Playground上试试):
" H0 F: B/ |5 ~
    Field: User.Name    Whole tag value : "mytag:"MyName""    Value of 'mytag': "MyName"Field: User.Email    Whole tag value : "mytag:"MyEmail""    Value of 'mytag': "MyEmail"' }) H" e+ p" R% v
GopherCon 2015 有一个关于结构标签的演示,称为:5 s) ^1 {3 F( W$ _7 b  y
多面性(幻灯片)结构标签(和视频)
8 D0 K/ ]( T* m3 T6 j以下是常用标签键列表:json- 由encoding/json使用包包,详见json.Marshal()
0 u" k* z4 g- c5 _xml- 由encoding/xml使用包包,详见xml.Marshal()9 \$ g- z5 B) Y  ?4 {: J
bson- 由gobson 使用,详见bson.Marshal(); 也由mongo-go在bson package doc 有详细说明0 Z  r) Y# O$ S% V' Z5 q  T( n
protobuf-github.com/golang/protobuf/proto用户在包文档中有详细说明
# I2 }2 E( [* O$ Tyaml- 由gopkg.in/yaml.v使用2包,详见yaml.Marshal()
. F6 C4 ?( F6 }+ {3 H# u; Gdb- 由github.com/jmoiron/sqlx使用包;也被github.com/go-gorp/gorp包使用" j3 S0 V: A9 k* O% u
orm- 由github.com/astaxie/beego/orm包使用,详细见模型 – Beego ORM" [8 _  E3 g7 m3 q' K6 D
gorm- 使用gorm.io/gorm,在他们的文档中可以找到示例  V, @, R1 G# h' {' k
valid- 由github.com/asaskevich/govalidator在项目页面上可以找到包使用的示例
2 d8 C& V& {4 B* sdatastore- 由appengine/datastore(Google App Engine 平台、Datastore 服务)使用,详见属性
8 m, ]" T3 g5 x$ Pschema- 用于github.com/gorilla/schema填充structHTML 表单值在包文档中有详细说明- R  ?" ~; S0 G5 p; Q) e( ?
asn- 由encoding/asn一包使用,详见asn1.Marshal()和asn1.Unmarshal()
  W* o4 i$ x: u6 A& M5 ^/ wcsv- 由github.com/gocarina/gocsv包使用
7 ^  @6 d- q4 V: z+ }. Tenv- 由github.com/caarlos0/env包使用
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则