В спецификации языка Go упоминается краткий обзор тегов:
За объявлением поля может следовать необязательный строковый литерал, который становится атрибутом для всех полей в соответствующем объявлении поля. Теги становятся видимыми через интерфейс отражения, но в остальном игнорируются.
// 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" }
Это очень короткое объяснение IMO, и мне было интересно, если кто-нибудь может предоставить мне, как будут использоваться эти теги?
go
reflection
struct
liamzebedee
источник
источник
Ответы:
Тег для поля позволяет вам прикрепить метаинформацию к полю, которую можно получить с помощью отражения. Обычно он используется для предоставления информации о преобразовании того, как поле структуры кодируется или декодируется из другого формата (или сохраняется / извлекается из базы данных), но вы можете использовать его для хранения любой мета-информации, которую вы хотите, либо предназначенной для другого пакет или для собственного использования.
Как упомянуто в документации
reflect.StructTag
, условно значение строки тега представляет собой разделенный пробелами списокkey:"value"
пар, например:key
Обычно обозначает пакет , что последующий"value"
для, например ,json
ключи обрабатываются / используютсяencoding/json
пакета.Если несколько данных должны быть переданы в
"value"
, обычно это указывается разделением запятой (','
), напримерОбычно значение тире (
'-'
)"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()
но отличает тег, не содержащий данный ключ, от тега, связывающего пустую строку с данным ключом» .Итак, давайте посмотрим на простой пример:
Вывод (попробуйте на Go Playground ):
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 ORMgorm
- используемые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
пакетомисточник
Вот очень простой пример использования тегов с
encoding/json
пакетом для управления интерпретацией полей во время кодирования и декодирования:Попробуйте вживую: http://play.golang.org/p/BMeR8p1cKf
Пакет json может просмотреть теги для поля и узнать, как отобразить поле структуры json <=>, а также дополнительные параметры, например, следует ли игнорировать пустые поля при сериализации обратно в json.
По сути, любой пакет может использовать отражение в полях для просмотра значений тегов и воздействия на эти значения. Немного больше информации о них в пакете
рефлекса http://golang.org/pkg/reflect/#StructTag :
источник
Это своего рода спецификации, которые определяют, как пакеты обрабатывают поле с тегами.
например:
json tag информирует
json
пакет, который маршаллировал вывод следующего пользователябудет так:
Другой пример -
gorm
теги пакетов, объявляющие, как должны выполняться миграции базы данных:В этом примере для поля
Email
с тегом gorm мы объявляем, что соответствующий столбец в базе данных для поля электронной почты должен иметь тип varchar и максимальную длину 100, а также иметь уникальный индекс.Другой пример -
binding
теги, которые используются в основном вgin
пакете.тег привязки в этом примере дает подсказку пакету джина о том, что данные, отправляемые в API, должны иметь поля пользователя и пароля, поскольку эти поля помечены как обязательные.
Таким образом, общие теги - это данные, которые пакетам необходимо знать, как они должны обращаться с данными различных структур типа, и лучший способ ознакомиться с тегами, которые нужны пакету, - это ЧИТАТЬ ДОКУМЕНТАЦИЮ ПАКЕТА ПОЛНОСТЬЮ.
источник