W specyfikacji języka Go wspomina krótki przegląd tagów:
Po deklaracji pola może następować opcjonalny znacznik literału łańcucha, który staje się atrybutem dla wszystkich pól w odpowiedniej deklaracji pola. Tagi są widoczne przez interfejs odbicia, ale w przeciwnym razie są ignorowane.
// A struct corresponding to the TimeStamp protocol buffer. // The tag strings define the protocol buffer field numbers. struct { microsec uint64 "field 1" serverIP6 uint64 "field 2" process string "field 3" }
To jest bardzo krótkie wyjaśnienie IMO i zastanawiałem się, czy ktokolwiek mógłby mi zapewnić, jaki byłby użytek z tych tagów?
go
reflection
struct
liamzebedee
źródło
źródło
Odpowiedzi:
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: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 (','
), npZwykle 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)
lubType.FieldByName(name string)
. Te metody zwracają wartość,StructField
która opisuje / reprezentuje pole struct; iStructField.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"
przezkey
Ciebie wartość. Konwencja jest realizowany / wbudowana w tejGet()
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:
Wyjście (wypróbuj na Go Playground ):
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 przezencoding/json
paczkę, wyszczególnione najson.Marshal()
xml
- używane przezencoding/xml
paczkę, wyszczególnione naxml.Marshal()
bson
- używane przez gobsona , wyszczególnione nabson.Marshal()
protobuf
- używane przezgithub.com/golang/protobuf/proto
, wyszczególnione w pakiecie docyaml
- używane przezgopkg.in/yaml.v2
paczkę, wyszczególnione nayaml.Marshal()
db
- używane przezgithub.com/jmoiron/sqlx
paczkę; używany również przezgithub.com/go-gorp/gorp
pakietorm
- używane przezgithub.com/astaxie/beego/orm
pakiet, wyszczególnione w Models - Beego ORMgorm
- używane przezgithub.com/jinzhu/gorm
pakiet, przykłady można znaleźć w ich doc: Modelsvalid
- używane przezgithub.com/asaskevich/govalidator
pakiet, przykłady można znaleźć na stronie projektudatastore
- używane przezappengine/datastore
(platforma Google App Engine, usługa magazynu danych), wyszczególnione w oknie Właściwościschema
- używane przezgithub.com/gorilla/schema
do wypełnieniastruct
wartości formularza HTML, wyszczególnionych w dokumencie pakietuasn
- używane przezencoding/asn1
opakowanie, wyszczególnione naasn1.Marshal()
iasn1.Unmarshal()
csv
- używane przezgithub.com/gocarina/gocsv
paczkęźródło
Oto naprawdę prosty przykład znaczników używanych z
encoding/json
pakietem do kontrolowania interpretacji pól podczas kodowania i dekodowania:Wypróbuj na żywo: http://play.golang.org/p/BMeR8p1cKf
Pakiet json może spojrzeć na znaczniki pola i dowiedzieć się, jak zamapować pole struktury json <=>, a także dodatkowe opcje, takie jak to, czy powinien ignorować puste pola podczas serializacji z powrotem do json.
Zasadniczo każdy pakiet może używać refleksji nad polami, aby patrzeć na wartości znaczników i działać na te wartości. Jest trochę więcej informacji na ich temat w pakiecie odzwierciedlającym
http://golang.org/pkg/reflect/#StructTag :
źródło
Jest to rodzaj specyfikacji, która określa, w jaki sposób pakiety traktują pole oznaczone.
na przykład:
Tag json informuje
json
pakiet, że zebrał dane wyjściowe kolejnego użytkownikawyglądałoby to tak:
innym przykładem są
gorm
znaczniki pakietów deklarujące, w jaki sposób należy przeprowadzić migrację bazy danych:W tym przykładzie dla pola
Email
z tagiem gorm deklarujemy, że odpowiednia kolumna w bazie danych dla adresu e-mail pola musi być typu varchar i mieć maksymalną długość 100, a także musi mieć unikalny indeks.innym przykładem są
binding
tagi, które są używane głównie wgin
pakiecie.tag wiązania w tym przykładzie daje wskazówkę do pakietu gin, że dane wysyłane do API muszą zawierać pola użytkownika i hasła, aby pola te były odpowiednio oznaczone.
Tak więc tagi generalne to dane, których pakiety potrzebują, aby wiedzieć, jak powinny traktować dane różnego typu, a najlepszym sposobem na zaznajomienie się z tagami, których potrzebuje pakiet, jest PEŁNE ODCZYT DOKUMENTACJI PAKIETU.
źródło