Maison >développement back-end >Golang >Comment créer un type en utilisant la réflexion avec un récepteur de pointeur

Comment créer un type en utilisant la réflexion avec un récepteur de pointeur

王林
王林avant
2024-02-06 08:45:071097parcourir

Comment créer un type en utilisant la réflexion avec un récepteur de pointeur

Contenu de la question

J'ai deux structures de tâches qui sont ShellTask​​CmdTask。创建了 TaskExecutor 接口并实现了 ShellTask​​CmdTask 指针接收器中的方法。并在运行时使用反射动态创建任务执行器。但是,当我在运行时运行程序时收到消息 panic: interface conversion: main.ShellTask​​ is not main.TaskExecutor: Missing method Run erreur, cependant, si je change le récepteur pointeur en récepteur sans pointeur, les choses commencent à fonctionner.

Comment créer un objet avec des pointeurs pour que les récepteurs de pointeurs fonctionnent.

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()
}

Lien Go Playground


Réponse correcte


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

Donc, si vous voulez que le pointeur soit pointé au lieu de la valeur, vous devez supprimer l'étape 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")
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer