Функция reflect.StructOf

Функция reflect.StructOf создает новый структурный тип на основе переданного слайса полей типа reflect.StructField. Она принимает один параметр - слайс структурных полей, а возвращает reflect.Type, представляющий созданную структуру. Эта функция полезна в ситуациях, когда структура не может быть определена на этапе компиляции, например, при работе с динамическими данными или при создании прокси-объектов.

Синтаксис

goreflect.StructOf(fields []reflect.StructField) reflect.Type

Пример 1

Давайте создадим простую структуру с двумя полями:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  fields := []reflect.StructField{
    {
      Name: "Name",
      Type: reflect.TypeOf(""),
    },
    {
      Name: "Age",
      Type: reflect.TypeOf(0),
    },
  }

  userType := reflect.StructOf(fields)
  user := reflect.New(userType).Elem()

  user.FieldByName("Name").SetString("Alice")
  user.FieldByName("Age").SetInt(30)

  fmt.Println(user.Interface())
}

Результат выполнения кода:

go{Alice 30}

Пример 2

Создадим структуру с полями разных типов и обработаем ее через рефлексию:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  fields := []reflect.StructField{
    {
      Name: "ID",
      Type: reflect.TypeOf(0),
    },
    {
      Name: "Active",
      Type: reflect.TypeOf(true),
    },
    {
      Name: "Data",
      Type: reflect.TypeOf([]string{}),
    },
  }

  itemType := reflect.StructOf(fields)
  item := reflect.New(itemType).Elem()

  item.FieldByName("ID").SetInt(123)
  item.FieldByName("Active").SetBool(true)
  item.FieldByName("Data").Set(reflect.ValueOf([]string{"a", "b", "c"}))

  for i := 0; i < itemType.NumField(); i++ {
    field := itemType.Field(i)
    value := item.Field(i)
    fmt.Printf("%s: %v\n", field.Name, value.Interface())
  }
}

Результат выполнения кода:

go"ID: 123"
"Active: true"
"Data: [a b c]"

Пример 3

Создадим структуру с аннотациями тегов:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  fields := []reflect.StructField{
    {
      Name: "FirstName",
      Type: reflect.TypeOf(""),
      Tag:  reflect.StructTag(`json:"first_name"`),
    },
    {
      Name: "LastName",
      Type: reflect.TypeOf(""),
      Tag:  reflect.StructTag(`json:"last_name"`),
    },
  }

  personType := reflect.StructOf(fields)

  for i := 0; i < personType.NumField(); i++ {
    field := personType.Field(i)
    fmt.Printf("%s: tag=%s\n", field.Name, field.Tag)
  }
}

Результат выполнения кода:

go"FirstName: tag=json:\"first_name\""
"LastName: tag=json:\"last_name\""

Смотрите также

  • функцию reflect.TypeOf,
    которая возвращает тип переданного значения
  • функцию reflect.ValueOf,
    которая возвращает рефлексивное значение
  • функцию reflect.StructField,
    которая описывает поле структуры для рефлексии
  • тип reflect.Type,
    который представляет тип любого значения в Go