Тип reflect.Method
Тип reflect.Method представляет собой структуру,
которая содержит информацию о конкретном методе,
полученную через пакет reflect. Этот тип используется
для описания методов структуры или интерфейса.
Структура reflect.Method содержит четыре поля:
Name (имя метода), PkgPath (путь пакета,
для экспортируемых методов пустой), Type
(тип метода как reflect.Type) и Func
(значение метода как reflect.Value).
Синтаксис
type Method struct {
Name string
PkgPath string
Type Type
Func Value
}
Для получения информации о методах используются методы
reflect.Type.NumMethod и
reflect.Type.Method.
Первый возвращает количество методов, второй -
информацию о методе по индексу.
Пример получения информации о методах структуры
Давайте создадим структуру с методами и получим информацию о них с помощью рефлексии:
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func (p Person) Greet() string {
return "Hello, " + p.Name
}
func (p Person) IsAdult() bool {
return p.Age >= 18
}
func main() {
p := Person{Name: "Alice", Age: 25}
t := reflect.TypeOf(p)
fmt.Println("Number of methods:", t.NumMethod())
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
fmt.Printf("Method %d: %+v\n", i, method)
}
}
Результат выполнения кода:
"Number of methods: 2"
"Method 0: {Name:Greet PkgPath: Type:func(main.Person) string Func:<func(main.Person) string Value>}"
"Method 1: {Name:IsAdult PkgPath: Type:func(main.Person) bool Func:<func(main.Person) bool Value>}"
Пример использования полей Method
Давайте продемонстрируем, как использовать поля
reflect.Method для получения имени и типа метода,
а также для вызова метода через рефлексию:
package main
import (
"fmt"
"reflect"
)
type Calculator struct{}
func (c Calculator) Add(a, b int) int {
return a + b
}
func (c Calculator) Multiply(a, b int) int {
return a * b
}
func main() {
calc := Calculator{}
t := reflect.TypeOf(calc)
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
fmt.Println("Method name:", method.Name)
fmt.Println("Method type:", method.Type)
// Вызов метода через рефлексию
args := []reflect.Value{
reflect.ValueOf(calc),
reflect.ValueOf(5),
reflect.ValueOf(3),
}
result := method.Func.Call(args)
fmt.Println("Result:", result[0].Interface())
fmt.Println("---")
}
}
Результат выполнения кода:
"Method name: Add"
"Method type: func(main.Calculator, int, int) int"
"Result: 8"
"---"
"Method name: Multiply"
"Method type: func(main.Calculator, int, int) int"
"Result: 15"
"---"
Пример работы с экспортируемыми и неэкспортируемыми методами
Поле PkgPath в reflect.Method позволяет
определить, является ли метод экспортируемым.
Для экспортируемых методов это поле пустое:
package main
import (
"fmt"
"reflect"
)
type Example struct{}
func (e Example) ExportedMethod() {}
func (e Example) unexportedMethod() {}
func main() {
t := reflect.TypeOf(Example{})
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
isExported := m.PkgPath == ""
fmt.Printf("Method: %s, Exported: %t, PkgPath: %q\n",
m.Name, isExported, m.PkgPath)
}
}
Результат выполнения кода:
"Method: ExportedMethod, Exported: true, PkgPath: \"\""
"Method: unexportedMethod, Exported: false, PkgPath: \"main\""
Смотрите также
-
тип
reflect.Type,
который предоставляет информацию о типах данных -
тип
reflect.Value,
который представляет значения данных в рефлексии -
функцию
reflect.Type.Method,
которая возвращает метод по индексу -
функцию
reflect.Type.NumMethod,
которая возвращает количество методов