4 回答

TA貢獻1883條經驗 獲得超3個贊
該方法的類型為func(*Environment)
。?斷言該類型并調用:
modules := make([]ModuleInfo, 1)
modules[0].Initialize = true
modules[0].Module = "Logger"
miValue := reflect.ValueOf(ModuleInit{})
for _, m := range modules {
? ? if m.Initialize {
? ? ? ? funcName := m.Module + "Init"
? ? ? ? method := miValue.MethodByName(funcName).Interface().(func(*Environment))
? ? ? ? method(&env)
? ? }
}
(注意兩個已解決的問題:模塊應該是"Logger"
,而不是"logger"
,方法需要一個*Environment
,而不是Environment
。)
如果找不到該方法或沒有正確的類型,上面的代碼將崩潰。這是帶有檢查以防止恐慌的代碼:
modules := make([]ModuleInfo, 1)
modules[0].Initialize = true
modules[0].Module = "Logger"
miValue := reflect.ValueOf(ModuleInit{})
for _, m := range modules {
? ? if m.Initialize {
? ? ? ? funcName := m.Module + "Init"
? ? ? ? method := miValue.MethodByName(funcName)
? ? ? ? if !method.IsValid() {
? ? ? ? ? ? fmt.Printf("method %s not found", funcName)
? ? ? ? ? ? continue
? ? ? ? }
? ? ? ? fn, ok := method.Interface().(func(*Environment))
? ? ? ? if !ok {
? ? ? ? ? ? fmt.Println("method is not func(*Environment)")
? ? ? ? ? ? continue
? ? ? ? }
? ? ? ? fn(&env)
? ? }
}

TA貢獻1735條經驗 獲得超5個贊
OP代碼中有幾個錯誤,
函數名稱未正確生成,
反映的方法實例沒有正確檢查有效性,
LoggerInit 的 env 參數是一個指針,傳入了一個值,
方法調用未正確完成。
這是固定版本 ( https://play.golang.org/p/FIEc6bTvGWJ )。
package main
import (
"flag"
"fmt"
"log"
"reflect"
"strings"
)
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 := strings.Title(m.Module) + "Init"
method := miValue.MethodByName(funcName)
log.Printf("%#v %v\n", method, funcName)
if !method.IsValid() || method.IsNil() {
break
}
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.
out := method.Call([]reflect.Value{reflect.ValueOf(env)})
fmt.Println(out) // A bunch of relfect.Values.
}
}
}
func (mi ModuleInit) LoggerInit(env Environment) {
var debugEnabled = *env.CLF.Debug
// ...and more stuff.
log.Println("LoggerInit ", debugEnabled)
}

TA貢獻1811條經驗 獲得超5個贊

TA貢獻1813條經驗 獲得超2個贊
您必須將env
變量包裝在 a 中[]reflect.Value
,因為reflect.Value.Call
需要一片reflect.Value
.
args := []reflect.Value{reflect.ValueOf(&env),} method.Call(args)
另外,您的代碼中有一些錯別字:
modules[0].Module = "Logger"
- 4 回答
- 0 關注
- 174 瀏覽
添加回答
舉報