Mit einem Tag für ein Feld können Sie dem Feld Metainformationen hinzufügen, die mithilfe von Reflektion erfasst werden können. Normalerweise wird es verwendet, um Transformationsinformationen darüber bereitzustellen, wie ein Strukturfeld in ein anderes Format codiert oder aus diesem dekodiert (oder aus einer Datenbank gespeichert / abgerufen) wird. Sie können es jedoch verwenden, um die gewünschten Metainformationen zu speichern, die entweder für ein anderes bestimmt sind Paket oder für den eigenen Gebrauch.
Wie in der Dokumentation von erwähnt reflect.StructTag, ist der Wert einer Tag-Zeichenfolge gemäß Konvention eine durch Leerzeichen getrennte Liste von key:"value"Paaren, zum Beispiel:
type User struct {
Name string `json:"name" xml:"name"`
}
Das keybezeichnet normalerweise das Paket, "value"für das das nachfolgende bestimmt ist, zum Beispiel werden jsonSchlüssel vom encoding/jsonPaket verarbeitet / verwendet .
Wenn mehrere Informationen in der übergeben werden sollen "value", wird dies normalerweise durch Trennen durch ein Komma ( ',') angegeben, z
Name string `json:"name,omitempty" xml:"name"`
Normalerweise bedeutet ein Strichwert ( '-') für das "value"Mittel, um das Feld vom Prozess auszuschließen (z. B. wenn jsondies bedeutet, dass dieses Feld nicht gemarshallt oder unmarshallt wird).
Beispiel für den Zugriff auf Ihre benutzerdefinierten Tags mithilfe von Reflection
Wir können Reflection ( reflectPaket) verwenden, um auf die Tag-Werte von Strukturfeldern zuzugreifen. Grundsätzlich müssen wir die Typeunserer Struktur erwerben , und dann können wir Felder abfragen, z . B. mit Type.Field(i int)oder Type.FieldByName(name string). Diese Methoden geben einen Wert zurück, der StructFieldein Strukturfeld beschreibt / darstellt. und StructField.Tagist ein Wert vom Typ, StructTagder einen Tag-Wert beschreibt / darstellt.
Zuvor haben wir über "Konvention" gesprochen . Diese Konvention bedeutet, dass Sie, wenn Sie sie befolgen, die StructTag.Get(key string)Methode verwenden können, die den Wert eines Tags analysiert und Ihnen den "value"von keyIhnen angegebenen Wert zurückgibt . Die Konvention ist in diese Get()Methode implementiert / eingebaut . Wenn Sie die Konvention nicht befolgen, Get()können Sie keine key:"value"Paare analysieren und finden, wonach Sie suchen. Das ist auch kein Problem, aber dann müssen Sie Ihre eigene Parsing-Logik implementieren.
Es gibt auch StructTag.Lookup()(wurde in Go 1.7 hinzugefügt), das "ähnlich ist, Get()aber das Tag, das den angegebenen Schlüssel nicht enthält, von dem Tag unterscheidet, das dem angegebenen Schlüssel eine leere Zeichenfolge zuordnet" .
Schauen wir uns also ein einfaches Beispiel an:
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"))
}
Ausgabe (versuchen Sie es auf dem Go-Spielplatz ):
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 hatte eine Präsentation über Struktur-Tags mit dem Namen:
Die vielen Gesichter von Struktur-Tags (Folie) (und ein Video )
Hier ist eine Liste häufig verwendeter Tag-Schlüssel:
json - vom encoding/jsonPaket verwendet, detailliert unterjson.Marshal()
xml - vom encoding/xmlPaket verwendet, detailliert unterxml.Marshal()
bson - von gobson verwendet , detailliert unterbson.Marshal()
protobuf - verwendet von github.com/golang/protobuf/proto, detailliert im Paketdokument
yaml - vom gopkg.in/yaml.v2Paket verwendet, detailliert unteryaml.Marshal()
db - vom github.com/jmoiron/sqlxPaket verwendet; wird auch vom github.com/go-gorp/gorpPaket verwendet
orm - Wird vom github.com/astaxie/beego/ormPaket verwendet und ist bei Models - Beego ORM aufgeführt
gorm - Beispiele, die vom github.com/jinzhu/gormPaket verwendet werden, finden Sie in ihrem Dokument: Modelle
valid - Beispiele, die vom github.com/asaskevich/govalidatorPaket verwendet werden, finden Sie auf der Projektseite
datastore- verwendet von appengine/datastore(Google App Engine-Plattform, Datenspeicherdienst), detailliert unter Eigenschaften
schema - wird verwendet github.com/gorilla/schema, um a structmit HTML-Formularwerten zu füllen , die im Paketdokument aufgeführt sind
asn - vom encoding/asn1Paket verwendet, detailliert unter asn1.Marshal()undasn1.Unmarshal()
csv - vom github.com/gocarina/gocsvPaket verwendet