如何从结构名称实例化在不同包中定义的结构并提供字段

How to instantiate struct that is defined in different package from struct name and provide fields

假设我在包 pkg:

中定义了一些 struct
package pkg

type Foo struct {
    FieldA string
    FieldB string
}

type Bar struct {
    FieldA string
    FieldB string
}

func (Foo) Show() {
    fmt.Println("Foo")
}

func (Bar) Show() {
    fmt.Println("Bar")
}

type Showable interface {
    Show()
}

Registry := map[string]Showable{
//not sure about value type^
    "Foo": Foo,     // staticcheck shows: not a type
    "Bar": Bar,     //
}
    

我想动态实例化 struct;像这样:

package main

import "url/user/pkg"

func main() {
    foo := pkg.Registry["Foo"]{
        FieldA: "A",
        FieldB: "B",
    }
    
    bar := pkg.Registry["Bar"]{
        FieldA: "X",
        FieldB: "Y",
    }
    foo.Show()
    bar.Show()
}

以上显然行不通。

有可能实现吗?我是 的新手。我看过 reflect,我试图用指针构建 Registry,空实例的指针,但无法找到一种方法来做到这一点。

最终,我正在尝试编写一个命令行实用程序来更改某些程序的主题。我已经编写了特定于程序的方法(如上面示例中的 Show),我正在尝试从 config.json 文件中读取特定于程序的参数,并动态创建实例。

如果我正确理解你想要达到的目标,这里是 方法:

registry.go:

package pkg

import (
    "fmt"
    "io"
)

type NewShowable func(r io.Reader) Showable

type Showable interface {
    Show()
}

type Foo struct {
    FieldA string
    FieldB string
}

func newFoo(r io.Reader) Showable {
    // Read config from r and construct Foo
    return Foo{}
}

func (Foo) Show() {
    fmt.Println("Foo")
}

type Bar struct {
    FieldA string
    FieldB string
}

func newBar(r io.Reader) Showable {
    // Read config from r and construct Bar
    return Bar{}
}

func (Bar) Show() {
    fmt.Println("Bar")
}

var Registry = map[string]NewShowable{
    "Foo": newFoo,
    "Bar": newBar,
}

main.go:

package main

import (
    "log"
    "os"

    "url/user/pkg"
)

func main() {
    f, err := os.Open("config.json")
    if err != nil {
        log.Fatalln(err)
    }
    defer f.Close()
    foo := pkg.Registry["Foo"](f)

    f2, err := os.Open("config2.json")
    if err != nil {
        log.Fatalln(err)
    }
    defer f2.Close()
    bar := pkg.Registry["Bar"](f2)
    foo.Show()
    bar.Show()
}