Un tag per un campo consente di allegare meta-informazioni al campo che possono essere acquisite mediante la riflessione. Di solito viene utilizzato per fornire informazioni di trasformazione su come un campo struct viene codificato o decodificato da un altro formato (o archiviato / recuperato da un database), ma è possibile utilizzarlo per archiviare qualsiasi meta-informazione desiderata, sia destinata a un altro pacchetto o per uso personale.
Come menzionato nella documentazione di reflect.StructTag
, per convenzione, il valore di una stringa tag è un elenco di key:"value"
coppie separate da spazi , ad esempio:
type User struct {
Name string `json:"name" xml:"name"`
}
Di key
solito indica il pacchetto a cui fa riferimento il successivo "value"
, ad esempio le json
chiavi vengono elaborate / utilizzate dal encoding/json
pacchetto.
Se devono essere passate più informazioni in "value"
, di solito vengono specificate separandole con una virgola ( ','
), ad es
Name string `json:"name,omitempty" xml:"name"`
Di solito un valore di trattino ( '-'
) per i "value"
mezzi per escludere il campo dal processo (ad esempio, nel caso in cui json
significhi non eseguire il marshalling o annullare il ripristino di quel campo).
Esempio di accesso ai tag personalizzati tramite reflection
Possiamo usare reflection ( reflect
pacchetto) per accedere ai valori dei tag dei campi struct. Fondamentalmente dobbiamo acquisire la Type
nostra struttura e quindi possiamo interrogare i campi, ad esempio con Type.Field(i int)
o Type.FieldByName(name string)
. Questi metodi restituiscono un valore di StructField
cui descrive / rappresenta un campo struct; ed StructField.Tag
è un valore di tipo StructTag
che descrive / rappresenta un valore di tag.
In precedenza abbiamo parlato di "convenzione" . Questo significa convenzione che se si seguono, si può usare il StructTag.Get(key string)
metodo che analizza il valore di una variabile e restituisce la "value"
del key
specificato. La convenzione è implementata / integrata in questo Get()
metodo. Se non segui la convenzione, Get()
non sarai in grado di analizzare le key:"value"
coppie e trovare quello che stai cercando. Anche questo non è un problema, ma è necessario implementare la propria logica di analisi.
Inoltre c'è StructTag.Lookup()
( è stato aggiunto in Go 1.7) che è "simile Get()
ma distingue il tag che non contiene la chiave data dal tag che associa una stringa vuota alla chiave data" .
Quindi vediamo un semplice esempio:
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"))
}
Output (provalo sul 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 ha presentato una presentazione sui tag struct chiamata:
I molti volti dei tag Struct (slide) (e un video )
Ecco un elenco di chiavi tag comunemente usate:
json
- usato dal encoding/json
pacchetto, dettagliato ajson.Marshal()
xml
- usato dal encoding/xml
pacchetto, dettagliato axml.Marshal()
bson
- usato da Gobson , dettagliato abson.Marshal()
protobuf
- usato da github.com/golang/protobuf/proto
, dettagliato nel pacchetto doc
yaml
- usato dal gopkg.in/yaml.v2
pacchetto, dettagliato ayaml.Marshal()
db
- utilizzato dal github.com/jmoiron/sqlx
pacchetto; utilizzato anche dal github.com/go-gorp/gorp
pacchetto
orm
- usato dal github.com/astaxie/beego/orm
pacchetto, dettagliato in Modelli - Beego ORM
gorm
- usati dal github.com/jinzhu/gorm
pacchetto, alcuni esempi possono essere trovati nel loro documento: Modelli
valid
- utilizzato dal github.com/asaskevich/govalidator
pacchetto, esempi sono disponibili nella pagina del progetto
datastore
- utilizzato da appengine/datastore
(piattaforma Google App Engine, servizio Datastore), dettagliato in Proprietà
schema
- utilizzato da github.com/gorilla/schema
per compilare a struct
con valori di modulo HTML, dettagliati nel documento del pacchetto
asn
- utilizzato dal encoding/asn1
pacchetto, dettagliato in asn1.Marshal()
easn1.Unmarshal()
csv
- utilizzato dal github.com/gocarina/gocsv
pacchetto