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 key
bezeichnet normalerweise das Paket, "value"
für das das nachfolgende bestimmt ist, zum Beispiel werden json
Schlüssel vom encoding/json
Paket 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 json
dies 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 ( reflect
Paket) verwenden, um auf die Tag-Werte von Strukturfeldern zuzugreifen. Grundsätzlich müssen wir die Type
unserer 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 StructField
ein Strukturfeld beschreibt / darstellt. und StructField.Tag
ist ein Wert vom Typ, StructTag
der 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 key
Ihnen 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/json
Paket verwendet, detailliert unterjson.Marshal()
xml
- vom encoding/xml
Paket 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.v2
Paket verwendet, detailliert unteryaml.Marshal()
db
- vom github.com/jmoiron/sqlx
Paket verwendet; wird auch vom github.com/go-gorp/gorp
Paket verwendet
orm
- Wird vom github.com/astaxie/beego/orm
Paket verwendet und ist bei Models - Beego ORM aufgeführt
gorm
- Beispiele, die vom github.com/jinzhu/gorm
Paket verwendet werden, finden Sie in ihrem Dokument: Modelle
valid
- Beispiele, die vom github.com/asaskevich/govalidator
Paket 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 struct
mit HTML-Formularwerten zu füllen , die im Paketdokument aufgeführt sind
asn
- vom encoding/asn1
Paket verwendet, detailliert unter asn1.Marshal()
undasn1.Unmarshal()
csv
- vom github.com/gocarina/gocsv
Paket verwendet