Вызов функции по строке с ее именем в golang

  • 1,582
  • 0
  • 0
  • 0
  • 3 года назад
package services

import (
    "reflect"
)

// GetLogFilesForService calls service code to find files for selected service
func GetLogFilesForService(rule Rule) []string {
    var logs []string
    CallMethod(&logs, rule.Name)
    return logs
}

// CallMethod is necessary to avoid map of functions
func CallMethod(i interface{}, methodName string) interface{} {
    var ptr reflect.Value
    var value reflect.Value
    var finalMethod reflect.Value

    value = reflect.ValueOf(i)

    // if we start with a pointer, we need to get value pointed to
    // if we start with a value, we need to get a pointer to that value
    if value.Type().Kind() == reflect.Ptr {
        ptr = value
        value = ptr.Elem()
    } else {
        ptr = reflect.New(reflect.TypeOf(i))
        temp := ptr.Elem()
        temp.Set(value)
    }

    // check for method on value
    method := value.MethodByName(methodName)
    if method.IsValid() {
        finalMethod = method
    }
    // check for method on pointer
    method = ptr.MethodByName(methodName)
    if method.IsValid() {
        finalMethod = method
    }

    if (finalMethod.IsValid()) {
        return finalMethod.Call([]reflect.Value{})[0].Interface()
    }

    // return or panic, method not found of either type
    i = make([]string, 0)
    return i
}