Go中标签的用途是什么?

Python016

Go中标签的用途是什么?,第1张

字段标签允许您将元信息附加到可以使用反射获取的字段上。通常,它用于提供有关如何将结构域编码为另一种格式(或从另一种格式存储(或从数据库中检索))的转换信息,但是您可以使用它存储想要存储的任何元信息,这些元信息既可以用于另一种包装或供您自己使用。

如的文档所述reflect.StructTag,按照惯例,标记字符串的值是用空格分隔的key:"value"成对列表,如:

type User struct {

Name string `json:"name" xml:"name"`

}

的key通常表示包,随后的"value"是,如json密钥被处理/使用的encoding/json包。

如果要在中传递多个信息"value",通常通过用逗号(',')隔开来指定它,如

Name string `json:"name,omitempty" xml:"name"`

通常用破折号('-')"value"表示将字段从过程中排除(如,在这种情况下,json表示不封送或取消封送该字段)。

使用反射访问自定义标签的示例

我们可以使用反射(reflect包)来访问结构字段的标记值。基本上,我们需要获取Type结构的,然后可以使用Type.Field(i

int)或查询字段Type.FieldByName(name

string)。这些方法返回的值StructField描述/表示一个struct字段;并且StructField.Tag是StructTag描述/表示标记值的类型值。

以前我们谈论过 “惯例” 。该公约的手段,如果你遵循它,你可以使用StructTag.Get(key

string)它解析变量的值,并返回该方法"value"的key指定。该公约实施/内置到这个Get()方法。如果不遵守约定,Get()将无法解析key:"value"对并找到您要查找的内容。这也不是问题,但是随后您需要实现自己的解析逻辑。

还有StructTag.Lookup()(在Go1.7中添加了),它 “类似于,Get()但是将不包含给定键的标签与将空字符串与给定键相关联的标签区分开”。因此,看一个简单的示例:

type User struct {

Name  string `mytag:"MyName"`

Email string `mytag:"MyEmail"`}

u := User{"Bob", "[email protected]"}

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"))

}

输出(在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上有一个关于struct标签的演示,名为:结构标签的许多面孔(幻灯片)

(和视频)以下是常用标签键的列表:

json-由encoding/json包装使用,详细说明json.Marshal()

xml-由encoding/xml包装使用,详细说明xml.Marshal()

bson-由gobson使用,详细说明bson.Marshal()

protobuf-由github.com/golang/protobuf/proto,在软件包doc中有详细说明

yaml-由gopkg.in/yaml.v2包装使用,详细说明yaml.Marshal()

db-由github.com/jmoiron/sqlx包装使用;也被github.com/go-gorp/gorp包装使用

orm-由github.com/astaxie/beego/orm包装使用,在“ 型号– Beego ORM”中有详细说明

gorm-由github.com/jinzhu/gorm软件包使用,示例可在其文档中找到:模型

valid-由github.com/asaskevich/govalidator软件包使用,示例可以在项目页面中找到

datastore-由appengine/datastore(Google App Engine平台,数据存储区服务)使用,在“ 属性”中有详细说明

schema-用于通过HTML表单值github.com/gorilla/schema填充(struct包文档中有详细说明)

asn-由encoding/asn1包装使用,详细说明在asn1.Marshal()和asn1.Unmarshal()

csv-由github.com/gocarina/gocsv包装使用

1. 部署简单

Go

编译生成的是一个静态可执行文件,除了glibc外没有其他外部依赖。这让部署变得异常方便:目标机器上只需要一个基础的系统和必要的管理、监控工具,完全不需要操心应用所需的各种包、库的依赖关系,大大减轻了维护的负担。

2. 并发性好

Goroutine和channel使得编写高并发的服务端软件变得相当容易,很多情况下完全不需要考虑锁机制以及由此带来的各种问题。单个Go应用也能有效的利用多个CPU核,并行执行的性能好。

3. 良好的语言设计

从学术的角度讲Go语言其实非常平庸,不支持许多高级的语言特性但从工程的角度讲,Go的设计是非常优秀的:规范足够简单灵活,有其他语言基础的程序员都能迅速上手。更重要的是

Go 自带完善的工具链,大大提高了团队协作的一致性。

4. 执行性能好

虽然不如 C 和 Java,但相比于其他编程语言,其执行性能还是很好的,适合编写一些瓶颈业务,内存占用也非常省。