Вызов метода через рефлексию в Go
Метод можно вызвать по имени-строке, если имя начинается с большой буквы. Рефлексия не видит методы с маленькой буквы даже в том же пакете.
Сначала берут значение-обертку над структурой,
затем ищут метод по текстовому имени и
получают callable значение. Запуск без
аргументов передают пустой список в
Call, результат лежит в срезе
значений.
Добавим метод подписи и вызовем его по имени из строки:
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
}
func (u User) Label() string {
return u.Name
}
func main() {
u := User{Name: "ann"}
v := reflect.ValueOf(u)
m := v.MethodByName("Label")
out := m.Call(nil)
fmt.Println(out[0].String())
}
На экране "ann". Имя в строке должно
совпадать с объявленным методом, включая
регистр первой буквы. Пустой список аргументов
подходит, когда у метода нет параметров.
Если метод возвращает несколько значений, их все лежат в срезе ответа по порядку:
package main
import (
"fmt"
"reflect"
)
type Pair struct {
A int
B int
}
func (p Pair) Sum() int {
return p.A + p.B
}
func main() {
p := Pair{A: 2, B: 3}
v := reflect.ValueOf(p)
m := v.MethodByName("Sum")
out := m.Call(nil)
fmt.Println(out[0].Int())
}
Дана структура:
type Tag struct {
Label string
}
func (t Tag) Caption() string {
return t.Label
}
x := Tag{Label: "go"}
Вызовите метод Caption у x
по имени из строки и выведите результат.
Дана структура:
type Box struct {
Value int
}
func (b Box) Twice() int {
return b.Value * 2
}
b := Box{Value: 4}
Получите число из метода Twice через
рефлексию и выведите его.
Дан следующий метод:
type Item struct {
Title string
}
func (i Item) title() string {
return i.Title
}
Скажите, найдет ли рефлексия метод с
именем title при поиске по строке.