我将如何让包在加载时将一些对象(例如函数)注册到注册表,以便向程序添加新包将自动向程序添加新功能,而无需修改其他包中的代码?
这是一个代码示例,应该说明我正在尝试做的事情。
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/reg/reg.go:
package reg
var registry = make(map[string]func() string)
func Register(name string, f func() string) {
registry[name] = f
}
func GetFunc(name string) (func() string, bool) {
f, ok := registry[name]
return f, ok
}
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 的镜头来思考这个问题太多,但是有什么方法可以完成一些有点像我正在拍摄的事情吗?如果没有,我会改变我的策略,我会学到一些关于 Go 做事方式的新知识。
提前致谢!