Тег для поля дозволяє приєднати метаінформацію до поля, яке можна отримати за допомогою відображення. Зазвичай він використовується для надання інформації про перетворення про те, як кодове поле кодується або декодується в іншому форматі (або зберігається / отримується з бази даних), але ви можете використовувати його для зберігання будь-якої метаінформації, яку ви хочете, або призначеної для іншого пакет або для власного користування.
Як зазначається в документації reflect.StructTag, за умовою значення рядка тегів - це розділений пробілом список key:"value"пар, наприклад:
type User struct {
Name string `json:"name" xml:"name"`
}
keyЗазвичай позначає пакет , що наступний "value"для, наприклад , jsonключі обробляються / використовуються encoding/jsonпакета.
Якщо у програмі потрібно передавати кілька відомостей "value", вона зазвичай задається шляхом відокремлення її комою ( ','), наприклад
Name string `json:"name,omitempty" xml:"name"`
Зазвичай значення тире ( '-') для "value"засобів виключення поля з процесу (наприклад, якщо jsonце означає - не маршалити чи не маршалити це поле).
Приклад доступу до власних тегів за допомогою відображення
Ми можемо використовувати відображення ( reflectпакет) для доступу до значень тегів полів структури. В основному нам потрібно придбати Typeструктуру, і тоді ми можемо запитувати поля, наприклад, з Type.Field(i int)або Type.FieldByName(name string). Ці методи повертають значення, StructFieldяке описує / представляє структурове поле; і StructField.Tagє значенням типу , StructTagякий описує / представляє собою значення тега.
Раніше ми говорили про "конвенцію" . Ця умова означає, що якщо ви дотримуєтесь цього, ви можете використовувати StructTag.Get(key string)метод, який аналізує значення тегу та повертає вам "value"вказане keyвами. Конвенції реалізовані / вбудована в цей Get()метод. Якщо ви не будете дотримуватися конвенції, Get()не зможете розібрати key:"value"пари і знайти те, що шукаєте. Це теж не проблема, але тоді вам потрібно реалізувати власну логіку розбору.
Також є StructTag.Lookup()(додано в Go 1.7), який є "як, Get()але відрізняє тег, що не містить даного ключа, від тегу, що асоціює порожній рядок із даним ключем" .
Отже, давайте подивимось простий приклад:
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"))
}
Результат (спробуйте на майданчику Go ):
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 відбулася презентація про теги Stru:
Теги безлічі облич структури (слайд) (і відео )
Ось перелік часто використовуваних тегів:
json - використовується encoding/jsonпакет, детально описаний наjson.Marshal()
xml - використовується encoding/xmlпакет, детально описаний наxml.Marshal()
bson - використаний Гобсон , детально описаний наbson.Marshal()
protobuf - використовується github.com/golang/protobuf/proto, детально описана в пакеті док
yaml - використовується gopkg.in/yaml.v2пакет, детально описаний наyaml.Marshal()
db - використовується github.com/jmoiron/sqlxпакетом; також використовується github.com/go-gorp/gorpпакетом
orm - використовується в github.com/astaxie/beego/ormупаковці, детально описана в моделях - Beego ORM
gorm - використовуваний github.com/jinzhu/gormпакет, приклади можна знайти в їх документі: Моделі
valid - використовуваний github.com/asaskevich/govalidatorпакет, приклади можна знайти на сторінці проекту
datastore- використовується appengine/datastore(платформа Google App Engine, сервіс Datastore), детально описана в розділі Властивості
schema - використовується github.com/gorilla/schemaдля заповнення structзначень форми HTML, детально описаних у пакеті документа
asn - використовується в encoding/asn1упаковці, детально описана в asn1.Marshal()таasn1.Unmarshal()
csv - використовується github.com/gocarina/gocsvпакетом