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 jsonclés sont traitées / utilisées par le encoding/jsonpackage.
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ù jsoncela 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 ( reflectpackage) pour accéder aux valeurs des balises des champs struct. Fondamentalement, nous devons acquérir le Typede 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 StructFieldqui décrit / représente un champ struct; et StructField.Tagest une valeur de type StructTagqui 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 keyvous 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/jsonpackage, détaillé àjson.Marshal()
xml - utilisé par le encoding/xmlpackage, 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.v2package, détaillé àyaml.Marshal()
db - utilisé par le github.com/jmoiron/sqlxpackage; également utilisé par github.com/go-gorp/gorppackage
orm - utilisé par le github.com/astaxie/beego/ormpackage, détaillé sur les modèles - Beego ORM
gorm - utilisé par le github.com/jinzhu/gormpackage, des exemples peuvent être trouvés dans leur doc: Modèles
valid - utilisé par le github.com/asaskevich/govalidatorpackage, 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/schemapour remplir unstruct avec des valeurs de formulaire HTML, détaillées dans le paquet doc
asn - utilisé par le encoding/asn1package, détaillé à asn1.Marshal()etasn1.Unmarshal()
csv - utilisé par le github.com/gocarina/gocsvpackage