首页 > 后端开发 > Golang > 正文

如何使用具有指针接收器的反射创建类型

王林
发布: 2024-02-06 08:45:07
转载
1077 人浏览过

如何使用具有指针接收器的反射创建类型

问题内容

我有两个任务结构,即 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 链接


正确答案


https://pkg.go.dev/[电子邮件受保护]#Value.Elem

因此,如果您想要指针而不是指向的值,则需要删除 e := newPtr.Elem() 步骤。

func GetTaskExecutor(name string) (TaskExecutor, error) {
    if k, ok := registry[name]; ok {
        p := reflect.New(k)
        f := p.Interface().(TaskExecutor)
        return f, nil
    }
    return nil, errors.New("no task handler found")
}
登录后复制

以上是如何使用具有指针接收器的反射创建类型的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:stackoverflow.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!