How to create a type using reflection with pointer receiver

王林
Release: 2024-02-06 08:45:07
forward
1076 people have browsed it

How to create a type using reflection with pointer receiver

Question content

I have two task structures, namely ShellTask​​ and CmdTask. Created the TaskExecutor interface and implemented the methods in the ShellTask​​ and CmdTask pointer receivers. And use reflection to dynamically create task executors at runtime. However, when I run the program at runtime I get the message panic: interface conversion: main.ShellTask​​ is not main.TaskExecutor: Missing method Run error, however, if I change the pointer receiver to non-pointer receiver and things will start working.

How to create an object with a pointer so that pointer receivers work.

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()
}
Copy after login

Go Playground Link


Correct Answer


https://pkg.go.dev/[email protected]#Value.Elem

So if you want the pointer instead of the value pointed to, you need to remove the e := newPtr.Elem() step.

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")
}
Copy after login

The above is the detailed content of How to create a type using reflection with pointer receiver. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!