Метод reflect.Value.Call
Метод reflect.Value.Call вызывает функцию,
представленную объектом reflect.Value.
В первый параметр мы передаем слайс аргументов
типа []reflect.Value, которые будут переданы
вызываемой функции. Метод возвращает слайс
[]reflect.Value с результатами выполнения
функции. Если функция не возвращает значений,
возвращается пустой слайс.
Синтаксис
func (v Value) Call(in []Value) []Value
Пример
Давайте вызовем простую функцию, которая складывает два целых числа:
package main
import (
"fmt"
"reflect"
)
func add(a, b int) int {
return a + b
}
func main() {
fn := reflect.ValueOf(add)
args := []reflect.Value{
reflect.ValueOf(10),
reflect.ValueOf(20),
}
res := fn.Call(args)
fmt.Println(res[0].Int())
}
Результат выполнения кода:
30
Пример
Давайте вызовем функцию с несколькими возвращаемыми значениями:
package main
import (
"fmt"
"reflect"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
func main() {
fn := reflect.ValueOf(divide)
args := []reflect.Value{
reflect.ValueOf(10.0),
reflect.ValueOf(2.0),
}
res := fn.Call(args)
fmt.Printf("%.1f, %v\n", res[0].Float(), res[1].Interface())
}
Результат выполнения кода:
"5.0, <nil>"
Пример
Давайте вызовем функцию, которая принимает вариативный параметр:
package main
import (
"fmt"
"reflect"
)
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func main() {
fn := reflect.ValueOf(sum)
args := []reflect.Value{
reflect.ValueOf([]int{1, 2, 3, 4, 5}),
}
res := fn.Call(args)
fmt.Println(res[0].Int())
}
Результат выполнения кода:
15
Пример
Давайте вызовем функцию, которая изменяет значение переданного указателя:
package main
import (
"fmt"
"reflect"
)
func setValue(p *int, val int) {
*p = val
}
func main() {
x := 10
fn := reflect.ValueOf(setValue)
args := []reflect.Value{
reflect.ValueOf(&x),
reflect.ValueOf(42),
}
fn.Call(args)
fmt.Println(x)
}
Результат выполнения кода:
42
Пример
Давайте вызовем метод структуры через отражение:
package main
import (
"fmt"
"reflect"
)
type Calculator struct {
value int
}
func (c Calculator) Add(n int) int {
return c.value + n
}
func main() {
calc := Calculator{value: 10}
method := reflect.ValueOf(calc).MethodByName("Add")
args := []reflect.Value{
reflect.ValueOf(5),
}
res := method.Call(args)
fmt.Println(res[0].Int())
}
Результат выполнения кода:
15
Смотрите также
-
метод
reflect.Value.Method,
который возвращает значение метода по индексу -
метод
reflect.Value.MethodByName,
который возвращает значение метода по имени -
метод
reflect.Value.Interface,
который преобразует отраженное значение в интерфейс -
метод
reflect.Value.IsValid,
который проверяет, содержит ли значение отражения данные