Функция reflect.MakeFunc

Функция reflect.MakeFunc создает новую функцию заданного типа, которая при вызове выполняет предоставленное замыкание. Первым параметром она принимает reflect.Type, описывающий сигнатуру создаваемой функции, вторым параметром - функцию func(args []reflect.Value) (results []reflect.Value), которая будет вызвана при обращении к созданной функции. Возвращаемое значение имеет тип reflect.Value, представляющий новую функцию.

Синтаксис

goreflect.MakeFunc(typ reflect.Type, fn func(args []reflect.Value) (results []reflect.Value)) reflect.Value

Пример

Давайте создадим функцию сложения двух целых чисел с помощью reflect.MakeFunc:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  addType := reflect.FuncOf(
    []reflect.Type{reflect.TypeOf(0), reflect.TypeOf(0)},
    []reflect.Type{reflect.TypeOf(0)},
    false,
  )

  addFn := reflect.MakeFunc(addType, func(args []reflect.Value) []reflect.Value {
    a := args[0].Int()
    b := args[1].Int()
    return []reflect.Value{reflect.ValueOf(a + b)}
  })

  result := addFn.Call([]reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20)})
  fmt.Println(result[0].Int())
}

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

go30

Пример

Давайте создадим функцию конкатенации двух строк с помощью reflect.MakeFunc:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  concatType := reflect.FuncOf(
    []reflect.Type{reflect.TypeOf(""), reflect.TypeOf("")},
    []reflect.Type{reflect.TypeOf("")},
    false,
  )

  concatFn := reflect.MakeFunc(concatType, func(args []reflect.Value) []reflect.Value {
    s1 := args[0].String()
    s2 := args[1].String()
    return []reflect.Value{reflect.ValueOf(s1 + s2)}
  })

  result := concatFn.Call([]reflect.Value{reflect.ValueOf("Hello, "), reflect.ValueOf("World!")})
  fmt.Println(result[0].String())
}

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

go"Hello, World!"

Пример

Давайте создадим функцию-обертку, которая логирует аргументы и результаты:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  multType := reflect.FuncOf(
    []reflect.Type{reflect.TypeOf(0), reflect.TypeOf(0)},
    []reflect.Type{reflect.TypeOf(0)},
    false,
  )

  multFn := reflect.MakeFunc(multType, func(args []reflect.Value) []reflect.Value {
    fmt.Printf("Arguments: %v, %v\n", args[0].Int(), args[1].Int())
    res := args[0].Int() * args[1].Int()
    fmt.Printf("Result: %v\n", res)
    return []reflect.Value{reflect.ValueOf(res)}
  })

  result := multFn.Call([]reflect.Value{reflect.ValueOf(3), reflect.ValueOf(5)})
  fmt.Println("Final result:", result[0].Int())
}

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

go"Arguments: 3, 5"
"Result: 15"
"Final result: 15"

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

  • функцию reflect.FuncOf,
    которая создает тип функции для использования с MakeFunc
  • функцию reflect.Value.Call,
    которая вызывает функцию через reflect.Value
  • функцию reflect.TypeOf,
    которая возвращает динамический тип значения
  • функцию reflect.ValueOf,
    которая создает reflect.Value из любого значения