Dynamic 随身携带的包裹?

Dynamic 随身携带的包裹?,dynamic,go,load-time,Dynamic,Go,Load Time,如何让包在加载时将某个对象(例如函数)注册到注册表,以便向程序添加新包将自动向程序添加新功能,而无需修改其他包中的代码 下面是一个代码示例,它应该说明我正在尝试做什么 src/say/say.go: package main import ( "os" "reg" ) func main() { if len(os.Args) != 2 { os.Stderr.WriteString("usage:\n say <what_to_say&g

如何让包在加载时将某个对象(例如函数)注册到注册表,以便向程序添加新包将自动向程序添加新功能,而无需修改其他包中的代码

下面是一个代码示例,它应该说明我正在尝试做什么

src/say/say.go:

package main

import (
    "os"
    "reg"
)

func main() {
    if len(os.Args) != 2 {
        os.Stderr.WriteString("usage:\n    say <what_to_say>\n")
        os.Exit(1)
    }

    cmd, ok := reg.GetFunc(os.Args[1])
    if ok {
        os.Stdout.WriteString(cmd())
        os.Stdout.Write([]byte{'\n'})
    } else {
        os.Stderr.WriteString("I can't say that!\n")
        os.Exit(1)
    }
}
src/hi/hi.go:

package hi

import (
    "reg"
}

func init() {
    reg.Register("hi", func() string {
        return "Hello there!"
    })
}
在编写这个代码时,我天真地认为可能go编译器会找到包hi并将其编译成二进制。然后,在加载时,init函数将运行。如果这就是工作原理,我可以插入如下内容,添加一个新的say no命令:

src/no/no.go:

package no

import (
    "reg"
)

func init() {
    reg.Register("no", func() string {
        return "Not a chance, bub."
    })
}
但是,它似乎不是这样工作的

我可能只是想了太多的问题,通过一个Pythonic镜头,但有没有一些方法来完成一些有点像我拍摄的东西?如果没有,我将改变我的策略,我将学会一些新的做事方式


提前谢谢

根据我读到的关于的内容,我认为如果您只是在say.go中导入的包列表中添加hi和no,那么您的示例就可以了。你这样做行吗


我知道您不想更改say.go中的代码,因此我认为这不是一个真正的解决方案。

根据我读到的关于的内容,我认为如果您只是在say.go中导入的软件包列表中添加hi和no,您的示例将起作用。你这样做行吗

我知道您不想更改say.go中的代码,因此我认为这不是一个真正的解决方案。

由于您必须使用导入才能让编译器添加包,我的建议是执行以下操作:

您可以只使用一个包和多个插入文件,而不是使用多个插入包。每个命令文件都放在同一个cmds包文件夹中。这是可能的,因为您可以在一个包中有多个init,并且无论您添加了多少新的drop-in文件,您都不必对say.go进行任何编辑

package main

import (
    "os"
    "reg"
    _ "cmds"
)
....
和以前的包裹编号

// Command no
package cmds

import (
    "reg"
)

func init() {
    reg.Register("no", func() string {
        return "Not a chance, bub."
    })
}
由于必须使用import才能让编译器添加包,因此我建议您执行以下操作:

您可以只使用一个包和多个插入文件,而不是使用多个插入包。每个命令文件都放在同一个cmds包文件夹中。这是可能的,因为您可以在一个包中有多个init,并且无论您添加了多少新的drop-in文件,您都不必对say.go进行任何编辑

package main

import (
    "os"
    "reg"
    _ "cmds"
)
....
和以前的包裹编号

// Command no
package cmds

import (
    "reg"
)

func init() {
    reg.Register("no", func() string {
        return "Not a chance, bub."
    })
}

好主意。如果没有一种不修改say.go的方法使其工作,那么这将是一个合理的折衷方案。。。如果成功的话。不幸的是,它不起作用。如果我只是在say.go的导入中添加hi和no,它会给我一个导入但未使用的错误,因为我从来没有在say.go的任何其他代码中引用hi或no。@user1483512:因为你必须导入uu-任何东西,才能得到使用它导入任何东西的副作用。哇,太酷了!我在文件里遗漏了这一点。这正式地使这个答案成为目前为止对我的特殊情况最好的建议。谢谢你们两位好主意。如果没有一种不修改say.go的方法使其工作,那么这将是一个合理的折衷方案。。。如果成功的话。不幸的是,它不起作用。如果我只是在say.go的导入中添加hi和no,它会给我一个导入但未使用的错误,因为我从来没有在say.go的任何其他代码中引用hi或no。@user1483512:因为你必须导入uu-任何东西,才能得到使用它导入任何东西的副作用。哇,太酷了!我在文件里遗漏了这一点。这正式地使这个答案成为目前为止对我的特殊情况最好的建议。谢谢你们两位令人惊叹的这正是我想要的。事后看来,我自己也应该想到这一点。不过有一点值得注意。我认为您仍然必须在cmds导入之前添加下划线,否则会出现导入且未使用的错误。i、 e.导入cmds。很高兴我能帮上忙。你是对的。我编辑了答案并添加了下划线。太棒了。这正是我想要的。事后看来,我自己也应该想到这一点。不过有一点值得注意。我认为您仍然必须在cmds导入之前添加下划线,否则会出现导入且未使用的错误。i、 e.导入cmds。很高兴我能帮上忙。你是对的。我编辑了答案并添加了下划线。