Golang — объяснение тегов структур

Сегодня мы попытаемся изучить структурные теги в Golang. Структура или struct — это способ определения пользовательских типов в Golang. В простых терминах struct можно объяснить следующим образом

Когда коллекция информации организована таким образом, что ее можно представить как единицу информации. Определенная единица может содержать данные с аналогичными атрибутами.

Например:

Вот пользовательский тип под названием Employee.

type Employee struct {
  FirstName string
  LastName  string
  EmployeeID string
  Salary     float64
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Если мы определим переменную emp типа Employee, то они будут иметь схожие атрибуты, такие как FirstName, LastName, EmployeeID и Salary. Доступ к которым можно получить следующим образом

// Assign the values
emp.FirstName = "Satyajit"
emp.LastName = "Roy"  
emp.EmployeeID = "1234"
emp.Salary = 111.0

// Print the values
fmt.Println(emp.FirstName)
fmt.Println(emp.LastName)
fmt.Println(emp.EmployeeID)
fmt.Println(emp.Salary)
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь структура tags — это небольшие части metadata, прикрепленные к fields в struct, которые предоставляют инструкции другому Go коду, который работает с struct.

Например:

Вот пользовательский тип под названием Employee может быть аннотирован как

type Employee struct {
  FirstName string `json: "first_name"`
  LastName  string `json: "last_name"`
  EmployeeID string `json: "employee_id"`
  Salary     float64 `json: "salary"`
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Код Go затем способен исследовать эти структуры и извлечь значения, присвоенные определенным ключам, которые он запрашивает. Структуры tags не оказывают никакого влияния на работу вашего кода без какого-либо другого кода, который их изучает.

Если мы читаем файл YAML или JSON, то мы можем аннотировать struct примерно так

type Employee struct {
  FirstName   string  `yaml: "first_name"`
  LastName    string  `yaml: "last_name"`
  EmployeeID  string  `yaml: "employee_id"`
  Salary      float64 `yaml: "salary"`
}

type Manager struct {
  ManagerFirstName   string  `json: "manager_first_name"`
  ManagerLastName    string  `json: "manager_last_name"`
  ManagerEmployeeID  string  `json: "manager_employee_id"`
  ManagerSalary      float64 `json: "manager_salary"`
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Приведенный ниже код считывает файл YAML и присваивает значения из файла YAML переменной

var mgr Manager
f, err := os.Open("manager_list.json")
 if err != nil {
  log.Fatalf("os.Open() failed with '%s'n", err)
 }
 defer func(f *os.File) {
  err := f.Close()
  if err != nil {

}
 }(f)

mrgObj := yaml.NewDecoder(f)
 err = mrgObj.Decode(&mgr)
 if err != nil {
  log.Fatalf("dec.Decode() failed with '%s'n", err)
 }
fmt.Println("%s %s employ_id is %s", mgr.FirstName, mgr.LastName, mgr.EmployeeID)
Войти в полноэкранный режим Выйти из полноэкранного режима

Кодировщик JSON в стандартной библиотеке использует теги struct в качестве аннотаций, указывающих кодировщику, как вы хотите назвать ваши поля в выходном JSON. Эти механизмы кодирования и декодирования JSON можно найти в пакете encoding/json.

Теперь, скажем, у вас есть пустое поле JSON, которое вы хотите удалить, тогда вы можете использовать omitempty и если объект JSON не имеет значения для этого ключа, то он не будет заполнен и пропущен.

type Manager struct {
  ManagerFirstName   string  `json: "manager_first_name"`
  ManagerLastName    string  `json: "manager_last_name"`
  ManagerEmployeeID  string  `json: "manager_employee_id"`
  ManagerSalary      float64 `json: "manager_salary,omitempty"`
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Если вы хотите игнорировать некоторое поле, то вы можете использовать - в тегах, и оно будет проигнорировано

type Manager struct {
  ManagerFirstName   string  `json: "manager_first_name"`
  ManagerLastName    string  `json: "manager_last_name"`
  ManagerEmployeeID  string  `json: "manager_employee_id"`
  ManagerSalary      float64 `json: "-"`
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Если вы хотите углубиться и получить доступ к тегам, то вы можете использовать пакет reflect, который позволяет отражение во время выполнения.

Использование тегов значительно упрощает навигацию по хранению данных и их представлений. Вы можете использовать go-playground/validator, который предоставляет гораздо больше возможностей для работы с тегами. Некоторые из них включают в себя следующие возможности

  • сравнение между полями
  • условие между полями
  • управление зависимостями между полями и многое другое…..

Для примера:

Приведенные ниже примеры показывают, как мы можем использовать go-playground/validator для валидации поля без написания дополнительного кода.

type Manager struct {
  ManagerFirstName   string  `json:"manager_first_name" validate:"required"`
  ManagerLastName    string  `json:"manager_last_name" validate:"required_if=ManagerFirstName"`
  ManagerEmployeeID  string  `json:"manager_employee_id" validate:"required, gte=1000,lt=10000"`
  ManagerSalary      float64 `json: "manager_salary,omitempty"`
}
Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше примере я смог проверить следующие поля

Итак, вместо того, чтобы писать код для проверки данных для некоторых фундаментальных и условных валидаций, мы можем использовать go-playground/validator, поскольку они поставляются со встроенной логикой для этого, полностью основанной на tags.

Надеюсь, это дало немного больше понимания о Golang Structures и Tags.

Счастливого кодинга!!!

Оцените статью
devanswers.ru
Добавить комментарий