Тег для поля позволяет вам прикрепить метаинформацию к полю, которую можно получить с помощью отражения. Обычно он используется для предоставления информации о преобразовании того, как поле структуры кодируется или декодируется из другого формата (или сохраняется / извлекается из базы данных), но вы можете использовать его для хранения любой мета-информации, которую вы хотите, либо предназначенной для другого пакет или для собственного использования.
Как упомянуто в документации 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 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 провел презентацию о структурных тегах под названием:
Теги Многогранности Структуры (слайд) (и видео )
Вот список часто используемых ключей тегов:
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, служба хранилища данных), подробно описано в разделе Свойства
schema
- используется github.com/gorilla/schema
для заполнения struct
значений HTML формы, подробно описано в пакете документов
asn
- используется в encoding/asn1
пакете, подробно на asn1.Marshal()
иasn1.Unmarshal()
csv
- используется github.com/gocarina/gocsv
пакетом