Uma tag para um campo permite anexar meta-informações ao campo que pode ser adquirido usando reflexão. Geralmente, ele é usado para fornecer informações de transformação sobre como um campo de estrutura é codificado ou decodificado de outro formato (ou armazenado / recuperado de um banco de dados), mas você pode usá-lo para armazenar qualquer meta-informação que desejar, destinada a outra pacote ou para seu próprio uso.
Conforme mencionado na documentação de reflect.StructTag, por convenção, o valor de uma sequência de tags é uma lista de key:"value"pares separados por espaço , por exemplo:
type User struct {
Name string `json:"name" xml:"name"`
}
O keynormalmente indica o pacote que o subsequente "value"é de, por exemplo, jsonas teclas são processados / utilizado pelo encoding/jsonpacote.
Se várias informações devem ser passadas no "value", normalmente elas são especificadas separando-as com uma vírgula ( ','), por exemplo
Name string `json:"name,omitempty" xml:"name"`
Geralmente, um valor de hífen ( '-') para os "value"meios de excluir o campo do processo (por exemplo, no caso de jsonisso significar não empacotar ou descompactar esse campo).
Exemplo de acesso às suas tags personalizadas usando reflexão
Podemos usar a reflexão ( reflectpacote) para acessar os valores das tags dos campos struct. Basicamente, precisamos adquirir Typenossa estrutura e, em seguida, podemos consultar os campos, por exemplo, com Type.Field(i int)ou Type.FieldByName(name string). Esses métodos retornam um valor StructFieldque descreve / representa um campo struct; e StructField.Tagé um valor do tipo StructTagque descreve / representa um valor de tag.
Anteriormente, conversamos sobre "convenção" . Essa convenção significa que, se você a seguir, poderá usar o StructTag.Get(key string)método que analisa o valor de uma tag e retorna "value"o que keyvocê especificar. A convenção é implementada / incorporada a este Get()método. Se você não seguir a convenção, Get()não poderá analisar key:"value"pares e encontrar o que está procurando. Isso também não é um problema, mas você precisa implementar sua própria lógica de análise.
Também existe StructTag.Lookup()(foi adicionado no Go 1.7) que é "semelhante, Get()mas distingue, a marca que não contém a chave especificada da marca que associa uma cadeia vazia à chave especificada" .
Então, vamos ver um exemplo simples:
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"))
}
Saída (experimente no 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"
O GopherCon 2015 teve uma apresentação sobre tags struct chamada:
As muitas faces das tags Struct (slide) (e um vídeo )
Aqui está uma lista das chaves de tag mais usadas:
json - usado pela encoding/jsonembalagem, detalhado emjson.Marshal()
xml - usado pela encoding/xmlembalagem, detalhado emxml.Marshal()
bson - usado por gobson , detalhado embson.Marshal()
protobuf - usado por github.com/golang/protobuf/proto, detalhado no pacote doc
yaml - usado pela gopkg.in/yaml.v2embalagem, detalhado emyaml.Marshal()
db - usado pela github.com/jmoiron/sqlxembalagem; também usado pelo github.com/go-gorp/gorppacote
orm - usado pelo github.com/astaxie/beego/ormpacote, detalhado em Modelos - Beego ORM
gorm - usado pelo github.com/jinzhu/gormpacote, exemplos podem ser encontrados em seus documentos: Modelos
valid - usado pelo github.com/asaskevich/govalidatorpacote, exemplos podem ser encontrados na página do projeto
datastore- usado por appengine/datastore(plataforma Google App Engine, serviço Datastore), detalhado em Propriedades
schema - usado por github.com/gorilla/schemapara preencher um structcom valores de formulário HTML, detalhados no documento do pacote
asn - usado pela encoding/asn1embalagem, detalhado em asn1.Marshal()easn1.Unmarshal()
csv - usado pela github.com/gocarina/gocsvembalagem