英文:
Import inside of a function
问题
正如标题所问,有没有办法在函数内部导入一个go文件?
我在考虑在我的discordgo(https://pkg.go.dev/github.com/bwmarrin/discordgo)程序中使用循环。
例如:
package main
import (
...
)
func main() {
client, _ := disocrdgo.New("Bot " + mytoken)
...
events, _ := ioutil.ReadDir("./events")
for event, _ := range events {
x, _ := import "MyApp/src/events/" + event // <---
client.AddHandler(x.executor) // 使用类型结构,其中executor是我想从导入的文件中使用的函数
}
...
}
我觉得有必要明确一下:
感谢您认真回答。
英文:
As the title asks, is there any way to import a go file from inside of a function?
I was thinking of using a loop for my discordgo(https://pkg.go.dev/github.com/bwmarrin/discordgo) program.
ex :
package main
import (
...
)
func main() {
client, _ := disocrdgo.New("Bot " + mytoken)
...
events, _ := ioutil.ReadDir("./events")
for event, _ := range events {
x, _ := import "MyApp/src/events/" + event // <---
client.AddHandler(x.executor) // using type struct where executor is the function i want to use from the imported file
}
...
}
I feel obligated to precise it so :
Thanks for your SERIOUS answers.
答案1
得分: 1
导入是编译器的概念,因此您无法在运行时导入包(通常情况下,运行程序的机器上甚至不存在源代码)。
您可以使用注册表模式来实现您所需的功能。
- 在events包中,创建一个存储处理程序的函数。在每个事件处理程序包的init函数中调用该函数。
- 在events包中,创建另一个函数,将存储的处理程序添加到客户端。
- 在主包中,导入您需要的所有事件处理程序包,并调用该第二个函数。
这基本上是标准库中sql和image包的工作方式。请参见sql.Register和image.RegisterFormat。
// events/registry.go
package events
var handlers = map[string]interface{}{}
func Register(name string, h interface{}) {
handlers[name] = h
}
func ConfigureClient(client *discordgo.Session) {
for _, h := range handlers {
client.AddHandler(h)
}
}
// events/foo/foo.go
package foo
import "MyApp/src/events"
func init() {
events.Register("foo", executor{})
}
type executor struct{}
// events/bar/bar.go
package bar
import "MyApp/src/events"
func init() {
events.Register("bar", executor{})
}
type executor struct{}
// main.go
package main
import (
_ "MyApp/src/events/foo"
_ "MyApp/src/events/bar"
// ...
)
func main() {
client, _ := discordgo.New("Bot " + mytoken)
events.ConfigureClient(client)
}
英文:
Imports are a compiler concept, so you cannot import packages at runtime (the source code doesn't even exist on the machine running your program, usually).
You can use the registry pattern to get close to what you're looking for.
- In the events package, create a function that stores handlers. Call that function in the init function for each event handler package.
- In the events package, create another function that adds the stored handlers to a client.
- In the main package, import all event handler packages you need and call that second function.
This is more or less how the sql and image packages in the standard library work. See sql.Register and image.RegisterFormat.
// events/registry.go
package events
var handlers = map[string]interface{}{}
func Register(name string, h interface{}) {
handlers[name] = h
}
func ConfigureClient(client *discordgo.Session) {
for _, h := range handlers {
client.AddHandler(h)
}
}
// events/foo/foo.go
package foo
import "MyApp/src/events"
func init() {
events.Register("foo", executor{})
}
type executor struct{}
// events/bar/bar.go
package bar
import "MyApp/src/events"
func init() {
events.Register("bar", executor{})
}
type executor struct{}
// main.go
package main
import (
_ "MyApp/src/events/foo"
_ "MyApp/src/events/bar"
// ...
)
func main() {
client, _ := discordgo.New("Bot " + mytoken)
events.ConfigureClient(client)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论