Heim >Backend-Entwicklung >Golang >So erstellen Sie einen Typ mithilfe von Reflektion mit Zeigerempfänger

So erstellen Sie einen Typ mithilfe von Reflektion mit Zeigerempfänger

王林
王林nach vorne
2024-02-06 08:45:071100Durchsuche

So erstellen Sie einen Typ mithilfe von Reflektion mit Zeigerempfänger

Frageninhalt

Ich habe zwei Aufgabenstrukturen, die ShellTask​​CmdTask。创建了 TaskExecutor 接口并实现了 ShellTask​​CmdTask 指针接收器中的方法。并在运行时使用反射动态创建任务执行器。但是,当我在运行时运行程序时收到消息 panic: interface conversion: main.ShellTask​​ is not main.TaskExecutor: Missing method Run fehlerhaft sind. Wenn ich jedoch den Zeigerempfänger in einen Nicht-Zeigerempfänger ändere, beginnen die Dinge zu funktionieren.

So erstellen Sie ein Objekt mit Zeigern, damit Zeigerempfänger funktionieren.

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


Richtige Antwort


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

Wenn Sie also den Zeiger anstelle des Werts haben möchten, auf den gezeigt wird, müssen Sie den Schritt e := newPtr.Elem() entfernen.

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

Das obige ist der detaillierte Inhalt vonSo erstellen Sie einen Typ mithilfe von Reflektion mit Zeigerempfänger. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:Mockgen erstellt keine MocksNächster Artikel:Mockgen erstellt keine Mocks