Une balise pour un champ vous permet d'attacher des méta-informations au champ qui peuvent être acquises par réflexion. Habituellement, il est utilisé pour fournir des informations de transformation sur la façon dont un champ struct est codé ou décodé à partir d'un autre format (ou stocké / récupéré à partir d'une base de données), mais vous pouvez l'utiliser pour stocker les méta-informations que vous souhaitez, destinées à un autre paquet ou pour votre propre usage.
Comme mentionné dans la documentation de reflect.StructTag
, par convention, la valeur d'une chaîne de balises est une liste de key:"value"
paires séparées par des espaces , par exemple:
type User struct {
Name string `json:"name" xml:"name"`
}
le key
désigne généralement le package pour lequel le suivant "value"
est destiné, par exemple les json
clés sont traitées / utilisées par le encoding/json
package.
Si plusieurs informations doivent être transmises dans le "value"
, elles sont généralement spécifiées en les séparant par une virgule ( ','
), par exemple
Name string `json:"name,omitempty" xml:"name"`
Habituellement, une valeur de tiret ( '-'
) pour les "value"
moyens d'exclure le champ du processus (par exemple, dans le cas où json
cela signifie de ne pas marshaler ou démarsaler ce champ).
Exemple d'accès à vos balises personnalisées à l'aide de la réflexion
Nous pouvons utiliser la réflexion ( reflect
package) pour accéder aux valeurs des balises des champs struct. Fondamentalement, nous devons acquérir le Type
de notre structure, puis nous pouvons interroger des champs, par exemple avec Type.Field(i int)
ou Type.FieldByName(name string)
. Ces méthodes renvoient une valeur StructField
qui décrit / représente un champ struct; et StructField.Tag
est une valeur de type StructTag
qui décrit / représente une valeur de balise.
Auparavant, nous parlions de «convention» . Ce moyen de la convention que si vous le suivez, vous pouvez utiliser la StructTag.Get(key string)
méthode qui analyse la valeur d'une variable et vous renvoie le "value"
de key
vous spécifiez. La convention est implémentée / intégrée dans cette Get()
méthode. Si vous ne respectez pas la convention, vous Get()
ne pourrez pas analyser les key:"value"
paires et trouver ce que vous cherchez. Ce n'est pas non plus un problème, mais vous devez ensuite implémenter votre propre logique d'analyse.
Il y a aussi StructTag.Lookup()
(a été ajouté dans Go 1.7) qui est "similaire Get()
mais distingue la balise ne contenant pas la clé donnée de la balise associant une chaîne vide à la clé donnée" .
Voyons donc un exemple 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"))
}
Sortie (essayez-la sur le 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 avait une présentation sur les balises struct appelée:
Les nombreux visages des balises Struct (diapositive) (et une vidéo )
Voici une liste des clés de balise couramment utilisées:
json
- utilisé par le encoding/json
package, détaillé àjson.Marshal()
xml
- utilisé par le encoding/xml
package, détaillé àxml.Marshal()
bson
- utilisé par gobson , détaillé àbson.Marshal()
protobuf
- utilisé par github.com/golang/protobuf/proto
, détaillé dans le paquet doc
yaml
- utilisé par le gopkg.in/yaml.v2
package, détaillé àyaml.Marshal()
db
- utilisé par le github.com/jmoiron/sqlx
package; également utilisé par github.com/go-gorp/gorp
package
orm
- utilisé par le github.com/astaxie/beego/orm
package, détaillé sur les modèles - Beego ORM
gorm
- utilisé par le github.com/jinzhu/gorm
package, des exemples peuvent être trouvés dans leur doc: Modèles
valid
- utilisé par le github.com/asaskevich/govalidator
package, des exemples peuvent être trouvés dans la page du projet
datastore
- utilisé par appengine/datastore
(plate-forme Google App Engine, service Datastore), détaillé à Propriétés
schema
- utilisé par github.com/gorilla/schema
pour remplir unstruct
avec des valeurs de formulaire HTML, détaillées dans le paquet doc
asn
- utilisé par le encoding/asn1
package, détaillé à asn1.Marshal()
etasn1.Unmarshal()
csv
- utilisé par le github.com/gocarina/gocsv
package