Метод reflect.Value.Method
Метод reflect.Value.Method возвращает метод значения
в виде нового значения reflect.Value, которое
представляет собой функцию. В первый параметр метод принимает
индекс метода, который можно получить через
reflect.Type.NumMethod. Метод работает только для
значений, которые имеют методы, иначе возникнет паника.
Синтаксис
func (v Value) Method(i int) Value
Пример
Давайте получим метод String у структуры
User по его индексу и вызовем его:
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
Age int
}
func (u User) String() string {
return fmt.Sprintf("User{Name: %s, Age: %d}", u.Name, u.Age)
}
func main() {
u := User{Name: "John", Age: 30}
v := reflect.ValueOf(u)
// Get the String method by index
method := v.Method(0)
res := method.Call(nil)
fmt.Println(res[0].String())
}
Результат выполнения кода:
"User{Name: John, Age: 30}"
Пример
Давайте получим все методы структуры и вызовем их в цикле:
package main
import (
"fmt"
"reflect"
)
type Calculator struct {
A int
B int
}
func (c Calculator) Add() int {
return c.A + c.B
}
func (c Calculator) Multiply() int {
return c.A * c.B
}
func (c Calculator) Sub() int {
return c.A - c.B
}
func main() {
calc := Calculator{A: 10, B: 5}
v := reflect.ValueOf(calc)
t := v.Type()
for i := 0; i < t.NumMethod(); i++ {
method := v.Method(i)
res := method.Call(nil)
fmt.Printf("Method %s result: %d\n", t.Method(i).Name, res[0].Int())
}
}
Результат выполнения кода:
"Method Add result: 15"
"Method Multiply result: 50"
"Method Sub result: 5"
Пример
Давайте вызовем метод с параметрами, передав их через
reflect.Value.Call:
package main
import (
"fmt"
"reflect"
)
type Printer struct {
Prefix string
}
func (p Printer) Print(message string, count int) string {
res := ""
for i := 0; i < count; i++ {
res += p.Prefix + " " + message + "\n"
}
return res
}
func main() {
p := Printer{Prefix: "INFO"}
v := reflect.ValueOf(p)
method := v.Method(0)
args := []reflect.Value{
reflect.ValueOf("Hello"),
reflect.ValueOf(3),
}
res := method.Call(args)
fmt.Println(res[0].String())
}
Результат выполнения кода:
"INFO Hello\nINFO Hello\nINFO Hello\n"
Пример
Давайте обработаем случай, когда метод возвращает несколько значений:
package main
import (
"fmt"
"reflect"
)
type Math struct {
A int
B int
}
func (m Math) Divide() (int, error) {
if m.B == 0 {
return 0, fmt.Errorf("division by zero")
}
return m.A / m.B, nil
}
func main() {
math := Math{A: 10, B: 2}
v := reflect.ValueOf(math)
method := v.Method(0)
res := method.Call(nil)
val := res[0].Int()
err := res[1].Interface()
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf("Result: %d\n", val)
}
}
Результат выполнения кода:
"Result: 5"
Смотрите также
-
метод
reflect.Value.Call,
который вызывает функцию или метод с аргументами -
метод
reflect.Value.MethodByName,
который получает метод по его имени -
метод
reflect.Type.Method,
который возвращает информацию о методе по индексу -
метод
reflect.Type.NumMethod,
который возвращает количество методов типа