0

我想在 Go 中执行以下操作,其中c/c.go包含:

package c

import (
    a "github.com/.../a"
    b "github.com/.../b"
)

func CallHandler(pkgName string) (err error) {
    pkg, err := DereferencePackage(pkgName)
    ...

    method, err := GetMethod(pkg, "Handler")

    if err != nil {
        return err
    }

    return method()
}

...

{
    err = CallHandler("a")
    ...
    err = CallHandler("b")
    ...
}

a/a.go包含:

package a

func Handler() (err error) {
    // Do whatever
    return err
}

b/b.go包含:

package b

func Handler() (err error) {
    // Do whatever
    return err
}

一个明显的解决方案是开关:

func CallHandler(pkgName string) (err error) {
    switch pkgName {
    case "a":
        return a.Handler()
    case "b":
        return b.Handler()
    default:
        return fmt.Errorf("no handler defined for %s", pkgName)
    }
}

但我想知道是否有可能更优雅地做到这一点,也许使用reflect包。问同样问题的另一种方法是,包可以成为 Go 中的接口吗?

4

1 回答 1

0

一个简单的解决方案是创建一个注册表包,其中包含

  1. 映射(键为字符串,即包的名称,值是函数指针)
  2. 在地图中填充数据的函数。
  3. 一个函数,用于根据传递的包名称从映射调用函数指针。

在每个包中,实现init()函数,将包名注册到Handler函数来注册包。

于 2021-01-13T18:08:41.953 回答