Метод reflect.Type.FieldByName

Метод FieldByName типа reflect.Type позволяет получить информацию о поле структуры по его имени. В качестве аргумента метод принимает строку с именем поля. Возвращает два значения: структуру reflect.StructField, содержащую информацию о поле, и булево значение, указывающее, было ли поле найдено. Если поле с указанным именем не существует, метод вернет пустую структуру и false.

Синтаксис

gofield, ok := reflect.TypeOf(obj).FieldByName("FieldName")

Пример

Рассмотрим простой пример получения информации о поле структуры:

gopackage main

import (
  "fmt"
  "reflect"
)

type User struct {
  Name string
  Age  int
}

func main() {
  user := User{Name: "John", Age: 30}
  t := reflect.TypeOf(user)

  field, ok := t.FieldByName("Name")
  if !ok {
    fmt.Println("Field not found")
    return
  }

  fmt.Println("Name:", field.Name)
  fmt.Println("Type:", field.Type)
}

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

go"Name: Name"
"Type: string"

Пример

Попробуем получить поле, которого нет в структуре:

gopackage main

import (
  "fmt"
  "reflect"
)

type User struct {
  Name string
  Age  int
}

func main() {
  user := User{Name: "John", Age: 30}
  t := reflect.TypeOf(user)

  _, ok := t.FieldByName("Email")
  if !ok {
    fmt.Println("Field Email not found")
  }
}

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

go"Field Email not found"

Пример

Получим доступ к тегам поля через структуру reflect.StructField:

gopackage main

import (
  "fmt"
  "reflect"
)

type User struct {
  Name string `json:"name" db:"username"`
  Age  int  `json:"age"`
}

func main() {
  user := User{Name: "John", Age: 30}
  t := reflect.TypeOf(user)

  field, ok := t.FieldByName("Name")
  if !ok {
    fmt.Println("Field not found")
    return
  }

  jsonTag := field.Tag.Get("json")
  dbTag := field.Tag.Get("db")

  fmt.Println("JSON tag:", jsonTag)
  fmt.Println("DB tag:", dbTag)
}

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

go"JSON tag: name"
"DB tag: username"

Пример

Получим информацию о вложенных полях структуры:

gopackage main

import (
  "fmt"
  "reflect"
)

type Address struct {
  City  string
  Index int
}

type User struct {
  Name  string
  Address Address
}

func main() {
  user := User{Name: "John", Address: Address{City: "NY", Index: 12345}}
  t := reflect.TypeOf(user)

  field, ok := t.FieldByName("Address")
  if !ok {
    fmt.Println("Field not found")
    return
  }

  fmt.Println("Field name:", field.Name)
  fmt.Println("Field type:", field.Type)

  // Получаем информацию о вложенных полях
  innerType := field.Type
  if innerType.Kind() == reflect.Struct {
    for i := 0; i < innerType.NumField(); i++ {
      innerField := innerType.Field(i)
      fmt.Println("Inner field:", innerField.Name, "Type:", innerField.Type)
    }
  }
}

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

go"Field name: Address"
"Field type: main.Address"
"Inner field: City Type: string"
"Inner field: Index Type: int"

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

  • метод reflect.Type.Field,
    который возвращает поле структуры по индексу
  • метод reflect.Type.NumField,
    который возвращает количество полей структуры
  • метод reflect.Value.FieldByName,
    который возвращает значение поля по имени
  • тип reflect.StructField,
    который представляет информацию о поле структуры