Una etiqueta para un campo le permite adjuntar metainformación al campo que se puede adquirir mediante la reflexión. Por lo general, se usa para proporcionar información de transformación sobre cómo se codifica o descodifica un campo de estructura desde otro formato (o se almacena / recupera de una base de datos), pero puede usarlo para almacenar cualquier metainformación que desee, ya sea para otro paquete o para su propio uso.
Como se menciona en la documentación de reflect.StructTag
, por convención, el valor de una cadena de etiqueta es una lista de key:"value"
pares separados por espacios , por ejemplo:
type User struct {
Name string `json:"name" xml:"name"`
}
Por lo key
general, denota el paquete para el que "value"
es posterior , por ejemplo, las json
claves son procesadas / utilizadas por el encoding/json
paquete.
Si se va a pasar información múltiple en "value"
, generalmente se especifica separándola con una coma ( ','
), p. Ej.
Name string `json:"name,omitempty" xml:"name"`
Por lo general, un valor de guión ( '-'
) para los "value"
medios para excluir el campo del proceso (por ejemplo, en el caso de json
que signifique no ordenar o desarmar ese campo).
Ejemplo de acceso a sus etiquetas personalizadas mediante reflexión
Podemos usar la reflexión ( reflect
paquete) para acceder a los valores de etiqueta de los campos de estructura. Básicamente, necesitamos adquirir el Type
de nuestra estructura, y luego podemos consultar los campos, por ejemplo, con Type.Field(i int)
o Type.FieldByName(name string)
. Estos métodos devuelven un valor StructField
que describe / representa un campo de estructura; y StructField.Tag
es un valor de tipo StructTag
que describe / representa un valor de etiqueta.
Anteriormente hablamos de "convención" . Esta convención significa que si la sigue, puede usar el StructTag.Get(key string)
método que analiza el valor de una etiqueta y le devuelve "value"
la key
que especifique. La convención se implementa / integra en este Get()
método. Si no sigue la convención, Get()
no podrá analizar key:"value"
pares y encontrar lo que está buscando. Eso tampoco es un problema, pero luego debe implementar su propia lógica de análisis.
También hay StructTag.Lookup()
(se agregó en Go 1.7) que es "como Get()
pero distingue la etiqueta que no contiene la clave dada de la etiqueta que asocia una cadena vacía con la clave dada" .
Entonces veamos un ejemplo simple:
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"))
}
Salida (pruébalo en 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 tuvo una presentación sobre etiquetas de estructura llamada:
Las muchas caras de las etiquetas de estructura (diapositiva) (y un video )
Aquí hay una lista de claves de etiqueta comúnmente utilizadas:
json
- utilizado por el encoding/json
paquete, detallado enjson.Marshal()
xml
- utilizado por el encoding/xml
paquete, detallado enxml.Marshal()
bson
- utilizado por gobson , detallado enbson.Marshal()
protobuf
- utilizado por github.com/golang/protobuf/proto
, detallado en el paquete doc
yaml
- utilizado por el gopkg.in/yaml.v2
paquete, detallado enyaml.Marshal()
db
- utilizado por el github.com/jmoiron/sqlx
paquete; también utilizado por github.com/go-gorp/gorp
paquete
orm
- utilizado por el github.com/astaxie/beego/orm
paquete, detallado en Modelos - Beego ORM
gorm
- utilizado por el github.com/jinzhu/gorm
paquete, se pueden encontrar ejemplos en su documento: Modelos
valid
- utilizado por el github.com/asaskevich/govalidator
paquete, se pueden encontrar ejemplos en la página del proyecto
datastore
- utilizado por appengine/datastore
(plataforma Google App Engine, servicio Datastore), detallado en Propiedades
schema
- Utilizado por github.com/gorilla/schema
para llenar un struct
formulario con valores HTML, detallado en el paquete doc.
asn
- utilizado por el encoding/asn1
paquete, detallado en asn1.Marshal()
yasn1.Unmarshal()
csv
- utilizado por el github.com/gocarina/gocsv
paquete