Тег для поля дозволяє приєднати метаінформацію до поля, яке можна отримати за допомогою відображення. Зазвичай він використовується для надання інформації про перетворення про те, як кодове поле кодується або декодується в іншому форматі (або зберігається / отримується з бази даних), але ви можете використовувати його для зберігання будь-якої метаінформації, яку ви хочете, або призначеної для іншого пакет або для власного користування.
Як зазначається в документації 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
пакетом