我有两个任务结构,即ShellTask
和CmdTask
。创建了一个TaskExecutor
接口,并在ShellTask
和CmdTask
指针接收器中实现了这些方法。并在运行时使用反射动态创建任务执行器。然而,当我在运行时运行程序时,得到错误消息panic: interface conversion: main.ShellTask is not main.TaskExecutor: missing method Run
,但是,如果我将指针接收器更改为非指针接收器,事情就开始工作了。
如何创建带指针的对象,使指针接收器工作
package main
import (
"errors"
"fmt"
"reflect"
)
type Task struct {
Name string
}
type TaskExecutor interface {
Run() error
}
type ShellTask struct {
*Task
}
func (t *ShellTask) Run() error {
fmt.Println("Running linux task")
return nil
}
type CmdTask struct {
*Task
}
func (t *CmdTask) Run() error {
fmt.Println("Running linux task")
return nil
}
var registry = make(map[string]reflect.Type)
func Register(moduleName string, v interface{}) {
registry[moduleName] = reflect.TypeOf(v)
}
func GetTaskExecutor(name string) (TaskExecutor, error) {
if k, ok := registry[name]; ok {
newPtr := reflect.New(k)
e := newPtr.Elem()
f := e.Interface().(TaskExecutor)
return f, nil
}
return nil, errors.New("no task handler found")
}
func main() {
Register("cmd", CmdTask{})
Register("shell", ShellTask{})
exec, err := GetTaskExecutor("shell")
if err != nil {
panic(err)
}
exec.Run()
}
Go Playground link
1条答案
按热度按时间5jvtdoz21#
https://pkg.go.dev/[email protected]#Value.Elem
Elem返回接口v包含或指针v指向的值。如果v的Kind不是Interface或Pointer,则会出现异常。如果v为nil,则返回零值。
所以,如果你想要指针而不是指向的值,你需要删除
e := newPtr.Elem()
步骤。