name keywords google etiquetas ejemplos description go reflection struct

keywords - ¿Cuáles son los usos para las etiquetas en Go?



meta tags google (2)

En la Especificación de idioma de Go , se menciona una breve descripción de las etiquetas:

Una declaración de campo puede ir seguida de una etiqueta literal de cadena opcional, que se convierte en un atributo para todos los campos en la declaración de campo correspondiente. Las etiquetas se hacen visibles a través de una interfaz de reflexión, pero de lo contrario se ignoran.

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

Esta es una explicación muy breve de la OMI, y me preguntaba si alguien podría proporcionarme el uso de estas etiquetas.


Este es un ejemplo realmente simple de las etiquetas que se utilizan con el paquete encoding/json para controlar cómo se interpretan los campos durante la codificación y la decodificación

Prueba en vivo: 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"}

El paquete json puede mirar las etiquetas del campo y recibir información sobre cómo asignar el campo struct json <=>, y también las opciones adicionales, como si se deben ignorar los campos vacíos al volver a serializar a json.

Básicamente, cualquier paquete puede usar la reflexión en los campos para ver los valores de las etiquetas y actuar sobre esos valores. Hay un poco más de información sobre ellos en el paquete reflect
reflect.StructTag :

Por convención, las cadenas de etiquetas son una concatenación de pares de "valores" de clave opcionalmente separados por espacios. Cada clave es una cadena no vacía que consta de caracteres que no son de control distintos del espacio (U + 0020 ''''), comillas (U + 0022 ''"'') y dos puntos (U + 003A '':''). Cada valor se cita utilizando los caracteres U + 0022 ''"'' y la sintaxis literal de la cadena Ir.


Una etiqueta para un campo le permite adjuntar metainformación al campo que puede adquirirse mediante la reflexión. Por lo general, se usa para proporcionar información de transformación sobre cómo se codifica o decodifica un campo de estructura desde otro formato (o se almacena / recupera de una base de datos), pero puede usarlo para almacenar la información meta que desee, ya sea para otra 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 etiquetas es una lista de pares de key:"value" separados por espacios, por ejemplo:

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

Por lo general, la key denota el paquete al que corresponde el "value" posterior, por ejemplo, las claves json son procesadas / utilizadas por el paquete encoding/json .

Si se va a pasar información múltiple en el "value" , normalmente se especifica separándola con una coma ( '','' ), por ejemplo

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

Por lo general, un valor de guión ( ''-'' ) para el "value" significa excluir el campo del proceso (por ejemplo, en el caso de json significa no ordenar o desmarcar ese campo).

Ejemplo de acceso a sus etiquetas personalizadas mediante reflexión.

Podemos usar la reflexión (paquete de reflect ) 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 campos, por ejemplo, con Type.Field(i int) o Type.FieldByName(name string) . Estos métodos devuelven un valor de 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 lo sigue, puede usar el StructTag.Get(key string) que analiza el valor de una etiqueta y le devuelve el "value" de la key que especifique. La convención está implementada / incorporada en este método Get() . Si no sigues la convención, Get() no podrá analizar key:"value" pares de key:"value" y encontrar lo que estás buscando. Eso tampoco es un problema, pero luego necesita 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" .

Así que veamos un ejemplo simple:

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

Salida (pruébalo en el 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 las etiquetas de estructura llamadas:

Las muchas caras de las etiquetas de Struct (diapositiva) (y un video )

Aquí hay una lista de las claves de etiquetas comúnmente usadas: