猿问

Go中的嵌入式程序包?

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


这是一个代码示例,该示例应说明我正在尝试执行的操作。


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的做事方式的新知识。


慕娘9325324
浏览 285回答 2
2回答

慕容3067478

根据我对init函数的了解,我认为您的示例只要将“ hi”和“ no”添加到要导入的软件包列表中,就可以使用say.go。如果这样做是行得通的吗?我知道您不想更改中的代码say.go,因此我认为这并不是真正的解决方案。
随时随地看视频慕课网APP

相关分类

Go
我要回答