目前,我将包名称作为字符串"Forecast",我需要将该字符串反映到包中,以便我可以调用该函数Run()。有没有办法进行这种反思?
为什么?
目前我正在 golang 中构建一个任务运行程序,其中所有任务都具有该功能Run(),并且我通过 kafka 消息接收要运行的任务"task": "Forecast",所以我试图避免switch类似的情况:
switch message.Task {
case "Forecast":
Forecast.Run()
case "SupplyCalculator":
SupplyCalculator.Run()
}
Run Code Online (Sandbox Code Playgroud)
而只是反映名称并调用函数,如下所示(PHP):
$task = new ReflectionClass("\\Task\\{$message->task}");
$task->run();
Run Code Online (Sandbox Code Playgroud)
包不是 Go 中的类型。
foo给定一个带有 function 的包Run,这有效......
v := reflect.ValueOf(foo.Run)
fmt.Println(v.Kind()) // func
Run Code Online (Sandbox Code Playgroud)
但这是一个语法错误:
v := reflect.ValueOf(foo)
Run Code Online (Sandbox Code Playgroud)
不要尝试使用反射,而是提前在映射中注册函数,然后在该映射中查找正确的函数来调用它。您可以提供一个简单的包来执行此操作,使用和tasks等方法。RegisterRun
// tasks.go
package tasks
type TaskFunc func() error // or whatever arguments your tasks take
var taskFuncs = map[string]TaskFunc{}
func Register(name string, fn TaskFunc) {
taskFuncs[name] = fn
}
func Run(name string) error {
if fn, found := taskFuncs[name]; found {
return fn()
}
return fmt.Errorf("Task %q not found", name)
}
Run Code Online (Sandbox Code Playgroud)
// forecast.go
package forecast
import "tasks"
tasks.Register("forecast", Run)
func Run() error {
// ...
}
Run Code Online (Sandbox Code Playgroud)
// main.go
err := tasks.Run(message.Task)
Run Code Online (Sandbox Code Playgroud)