首頁 > 後端開發 > 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學習者快速成長!