当前位置: 首页 > 知识库问答 >
问题:

结构标签在 Go 中有什么用途?

房光临
2023-03-14

在Go语言规范中,提到了对标签的简要概述:

字段声明之后可能会有一个可选的字符串文字标记,该标记将成为相应字段声明中所有字段的属性。标记通过反射界面可见,但在其他情况下被忽略。

// 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"
}

这是一个非常简短的解释,我想知道是否有人能给我提供这些标签的用途?

共有3个答案

哈骞仕
2023-03-14
匿名用户

它是某种规范,用于指定包如何处理标记的字段。

例如:

type User struct {
    FirstName string `json:"first_name"`
    LastName string `json:"last_name"`
}

json标记通知< code>json包已封送以下用户的输出

u := User{
        FirstName: "some first name",
        LastName:  "some last name",
    }

将是这样的:

{"first_name":"some first name","last_name":"some last name"}

另一个例子是gorm包标签声明了必须如何完成数据库迁移:

type User struct {
  gorm.Model
  Name         string
  Age          sql.NullInt64
  Birthday     *time.Time
  Email        string  `gorm:"type:varchar(100);unique_index"`
  Role         string  `gorm:"size:255"` // set field size to 255
  MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null
  Num          int     `gorm:"AUTO_INCREMENT"` // set num to auto incrementable
  Address      string  `gorm:"index:addr"` // create index with name `addr` for address
  IgnoreMe     int     `gorm:"-"` // ignore this field
}

在本例中,对于带有gorm标记的字段<code>Email</code>我们声明数据库中该字段Email的对应列必须为varchar类型,最大长度为100,并且必须具有唯一索引。

另一个例子是绑定标记,它们主要用于ginpackage。

type Login struct {
    User     string `form:"user" json:"user" xml:"user"  binding:"required"`
    Password string `form:"password" json:"password" xml:"password" binding:"required"`
}


var json Login
if err := c.ShouldBindJSON(&json); err != nil {
     c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
     return
}

示例中的绑定标签向gin包提供提示,即发送到API的数据必须具有用户和密码字段,因为这些字段根据需要进行标记。

因此,通用标签是包需要知道如何处理不同结构类型的数据的数据,熟悉包需要的标签的最好方法是完整地阅读包文档。

彭开畅
2023-03-14

这是一个非常简单的示例,说明标签编码/json包一起使用,以控制在编码和解码期间如何解释字段:

现场试用:http://play.golang.org/p/BMeR8p1cKf

package main

import (
    "fmt"
    "encoding/json"
)

type Person struct {
    FirstName  string `json:"first_name"`
    LastName   string `json:"last_name"`
    MiddleName string `json:"middle_name,omitempty"`
}

func main() {
    json_string := `
    {
        "first_name": "John",
        "last_name": "Smith"
    }`

    person := new(Person)
    json.Unmarshal([]byte(json_string), person)
    fmt.Println(person)

    new_json, _ := json.Marshal(person)
    fmt.Printf("%s\n", new_json)
}

// *Output*
// &{John Smith }
// {"first_name":"John","last_name":"Smith"}

json 包可以查看字段的标记,并被告知如何映射 json

基本上,任何包都可以在字段上使用反射来查看标记值并对这些值执行操作。在反射包中有更多关于它们
的信息 http://golang.org/pkg/reflect/#StructTag:

按照惯例,标记字符串是可选空格分隔的键:“值”对的串联。每个键都是非空字符串,由除空格(U 0020 ' ')、引号(U 0022 ' " ')和冒号(U 003A ':')以外的非控制字符组成。每个值都用U 0022 ' " '字符和Go字符串文字语法引用。

简培
2023-03-14

字段的标记允许您将元信息附加到可以使用反射获取的字段。通常,它用于提供有关如何将结构字段编码为其他格式或从其他格式解码(或从数据库中存储/检索)的转换信息,但您可以使用它存储您想要存储的任何元信息,无论是用于另一个包还是供您自己使用。

如《反映》的文献中所述。StructTag,按照惯例,标签字符串的值是键:“value”对的空格分隔列表,例如:

type User struct {
    Name string `json:"name" xml:"name"`
}

< code>key通常表示后续< code >“value”所针对的包,例如< code > JSON key由< code>encoding/json包处理/使用。

如果要在的“值”中传递多个信息,通常通过用逗号(,“)分隔来指定,例如。

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

通常,“value”的破折号值(“-”)意味着将该字段从进程中排除(例如,在json的情况下,它意味着不封送或解封该字段)。

我们可以使用反射(反射包)来访问结构字段的标记值。基本上,我们需要获取结构的类型,然后我们可以查询字段,例如使用Type.Field(i int)Type.FieldByName(name string)。这些方法返回 StructField 的值,该值描述 / 表示结构字段;StructField.Tag 是类型为 [StructTag] 6 的值,它描述 /表示标记值。

之前我们谈到了“惯例”。此约定意味着,如果您遵循它,则可以使用 StructTag.Get(键字符串) 方法,该方法分析标记的值并返回您指定的“值”。该约定已实现/内置于此 Get() 方法中。如果不遵循约定,Get() 将无法解析 key:“value” 对并找到所需的内容。这也不是问题,但您需要实现自己的解析逻辑。

还有StructTag.Lookup()(在Go 1.7中添加),它“类似于Get(),但将不包含给定键的标签与将空字符串与给定键相关联的标签区分开来”。

让我们看一个简单的例子:

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

输出(在Go操场上试试):

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有一个关于结构标签的演讲,称为:

结构标签的许多面(幻灯片)(和一个视频)

 类似资料:
  • 问题内容: 在Go语言规范中,它提到了标签的简要概述: 字段声明后可以跟一个可选的字符串文字标签,该标签成为相应字段声明中所有字段的属性。这些标签通过反射界面可见,但在其他情况下将被忽略。 这是IMO的简短解释,我想知道是否有人可以为我提供这些标签的用途? 问题答案: 字段标签允许您将元信息附加到可以使用反射获取的字段上。通常,它用于提供有关如何将结构域编码为另一种格式(或从另一种格式存储(或从数

  • 主要内容:结构体标签的格式,从结构体标签中获取值,结构体标签格式错误导致的问题通过 reflect.Type 获取结构体成员信息 reflect.StructField 结构中的 Tag 被称为结构体标签(Struct Tag)。结构体标签是对结构体字段的额外信息标签。 JSON、BSON 等格式进行序列化及对象关系映射(Object Relational Mapping,简称 ORM)系统都会用到结构体标签,这些系统使用标签设定字段在处理时应该具备的特殊属性和可能发生的行

  • 问题内容: 通常,我将初始化一个类似的结构: 但是,我最近看到了用括号初始化的代码: 返回相同的名称。 括号中的内容起什么作用?何时首选? 这是一些Go代码可以尝试一下: 游乐场:https : //play.golang.org/p/_gsaruS_DVi 问题答案: 没什么特别的,那两行是相同的。 但是,例如,当您要在语句中使用它时,将需要使用括号,否则会出现编译时错误: 结果是: 预期的布尔

  • 本文向大家介绍noscript标签有什么作用?相关面试题,主要包含被问及noscript标签有什么作用?时的应答技巧和注意事项,需要的朋友参考一下 如果浏览器不支持js,noscript会帮助我们显示一些信息 https://stackoverflow.com/questions/2170484/shouldnt-we-use-noscript-element

  • 问题内容: 我开始使用诊断CSS样式表,例如 建议的规则之一突出显示类型为Submit的输入标签,并建议将其用作更具语义的解决方案。您遇到过的类型提交(例如与浏览器兼容性)的优缺点是什么? 明确地说,我了解的规格,它具有定义的开始和结束,可以包含各种元素,而输入是单线态,不能包含任何东西。我实质上想知道的是它是否损坏。我想知道当前按钮的可用性。不幸的是,下面的第一个答案似乎确实暗示它不能用于表格之