这是使用 Go Reflect 调用函数的后续内容。
为了简化问题,我尽可能地删减了一些值,并且~希望~并没有在这个过程中让它变得不清楚。我在底部附近的代码“method.Call(env)”上遇到错误。
理想情况下,我想做的是尽量减少反射的使用,就像 ThunderCat 在上一个问题上所做的那样:
method := miType.Method(i).Func.Interface().(func(core.ModuleInfo) core.ModuleInfo)
但如果这不可能,那么最简单的方法就可以了。如果这似乎是一个基本问题,我很抱歉,我对 Go 很陌生。
我得到的错误是:
cannot use env (type Environment) as type []reflect.Value in argument to method.Call
这是因为我想用正确的签名将方法声明给函数,就像在上一个问题中所做的那样,但是经过相当多的玩弄之后,我还没有完全明白。
简化代码:
package main
import (
"flag"
"fmt"
"reflect"
)
type CommandLineFlags struct {
Debug *bool
}
type Environment struct {
CLF CommandLineFlags
}
type ModuleInfo struct {
Initialize bool // Flag: True of module has Initialization function and it should be called. Default: false
Module string // Name of the module. No need to hard code, will be set during initialization.
}
type ModuleInit struct{}
func main() {
var env Environment
env.CLF.Debug = flag.Bool("dbg", false, "Enables Debug Messages")
flag.Parse()
modules := make([]ModuleInfo, 1)
modules[0].Initialize = true
modules[0].Module = "logger"
miValue := reflect.ValueOf(ModuleInit{})
// miType := reflect.TypeOf(ModuleInit{})
for _, m := range modules {
if m.Initialize {
funcName := m.Module + "Init"
method := miValue.MethodByName(funcName)
fmt.Println(funcName)
// Would like to do something like this
// ...Func.Interface().(func(core.ModuleInit) core.ModuleInit)
// like is done with the referenced quesiton above so as to minimize the use of reflect calls.
method.Call(env)
}
}
}
func (mi ModuleInit) LoggerInit(env *Environment) {
var debugEnabled = *env.CLF.Debug
// ...and more stuff.
}