Znacznik pola umożliwia dołączenie do pola meta-informacji, które można uzyskać za pomocą odbicia. Zwykle służy do dostarczania informacji o transformacji, w jaki sposób pole struct jest kodowane lub dekodowane z innego formatu (lub przechowywane / pobierane z bazy danych), ale możesz go użyć do przechowywania dowolnych meta-informacji, które chcesz, albo przeznaczonych dla innego pakiet lub na własny użytek.
Jak wspomniano w dokumentacji reflect.StructTag
, zgodnie z konwencją wartość ciągu znacznika jest oddzieloną spacją listą key:"value"
par, na przykład:
type User struct {
Name string `json:"name" xml:"name"`
}
key
Zwykle oznacza pakietu, który następnie "value"
jest, na przykład, json
klucze są przetwarzane / wykorzystywane przezencoding/json
pakiet.
Jeśli ma zostać przekazanych wiele informacji "value"
, zwykle określa się je, oddzielając je przecinkiem ( ','
), np
Name string `json:"name,omitempty" xml:"name"`
Zwykle wartość myślnika ( '-'
) dla "value"
sposobu wykluczenia pola z procesu (np. W przypadkujson
gdy oznacza to nie marszrowanie lub odmarszowanie tego pola).
Przykład uzyskiwania dostępu do niestandardowych tagów za pomocą odbicia
Możemy użyć refleksji ( reflect
pakietu), aby uzyskać dostęp do wartości znaczników pól struct. Zasadniczo musimy zdobyć Type
naszą strukturę, a następnie możemy wyszukiwać pola np. Za pomocą Type.Field(i int)
lub Type.FieldByName(name string)
. Te metody zwracają wartość, StructField
która opisuje / reprezentuje pole struct; i StructField.Tag
jest wartością typuStructTag
która opisuje / reprezentuje wartość znacznika.
Wcześniej rozmawialiśmy o „konwencji” . Ta konwencja oznacza, że jeśli będziesz go przestrzegać, możesz użyć StructTag.Get(key string)
metody, która analizuje wartość znacznika i zwraca ci określoną "value"
przez key
Ciebie wartość. Konwencja jest realizowany / wbudowana w tej Get()
metodzie. Jeśli nie zastosujesz się do konwencji, Get()
nie będziesz mógł przeanalizowaćkey:"value"
par i znaleźć tego, czego szukasz. To też nie jest problem, ale musisz zaimplementować własną logikę parsowania.
Jest też StructTag.Lookup()
(został dodany w wersji 1.7), który jest „podobny, Get()
ale odróżnia znacznik niezawierający danego klucza od znacznika kojarzącego pusty ciąg z danym kluczem” .
Zobaczmy więc prosty przykład:
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"))
}
Wyjście (wypróbuj na 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 miał prezentację na temat tagów struktur o nazwie:
The Many Faces of Struct Tags (slajd) (i wideo )
Oto lista najczęściej używanych kluczy tagów:
json
- używane przez encoding/json
paczkę, wyszczególnione najson.Marshal()
xml
- używane przez encoding/xml
paczkę, wyszczególnione naxml.Marshal()
bson
- używane przez gobsona , wyszczególnione nabson.Marshal()
protobuf
- używane przez github.com/golang/protobuf/proto
, wyszczególnione w pakiecie doc
yaml
- używane przez gopkg.in/yaml.v2
paczkę, wyszczególnione nayaml.Marshal()
db
- używane przez github.com/jmoiron/sqlx
paczkę; używany również przez github.com/go-gorp/gorp
pakiet
orm
- używane przez github.com/astaxie/beego/orm
pakiet, wyszczególnione w Models - Beego ORM
gorm
- używane przez github.com/jinzhu/gorm
pakiet, przykłady można znaleźć w ich doc: Models
valid
- używane przez github.com/asaskevich/govalidator
pakiet, przykłady można znaleźć na stronie projektu
datastore
- używane przez appengine/datastore
(platforma Google App Engine, usługa magazynu danych), wyszczególnione w oknie Właściwości
schema
- używane przez github.com/gorilla/schema
do wypełnienia struct
wartości formularza HTML, wyszczególnionych w dokumencie pakietu
asn
- używane przez encoding/asn1
opakowanie, wyszczególnione na asn1.Marshal()
iasn1.Unmarshal()
csv
- używane przez github.com/gocarina/gocsv
paczkę