I have a folder containing multiple packages (each a seperate module), and i want to iterate through each package and call a "Name" variable from each one, so that i can print out a name and description of each package then call its respective run function. in python there is the __import__ function. is there something similar to this for go?
#Can i iterate through package modules like i can in python?
12 messages · Page 1 of 1 (latest)
Is your intention to create some kind of plugin/module system for your application? If so, I would not implement it this way in Go.
No i just want to be able to quickly add new code without having to store everything in an array
Apart from accessing the Name variable in each package, what do you intend to do?
I'll leave the abstract base class thing for another day. I would not implement what you're describing the way you've done it in Python in Go.
There is a reasonably common pattern for this kind of thing though, which is to create a kind of "registry" of things.
Here's how it works:
First, let's describe an interface for starting/stopping (or whatever operations make sense) the components of your application
type Component interface {
Start() error
}
In the root of your plugins package, create a global registry, something like this:
var Components map[string]Component
func Register(name string, comp Component) {
Components[name] = comp
}
Now in each sub-package, where each component is defined, use the init function to add that package's component(s) to the registry:
// package1/component.go
func init() {
components.Register("package1", &Component1{})
}
// package2/component.go
func init() {
components.Register("package2", &Component2{})
}
After package initialization, the Components map will have registered all imported package components. Which means you could do something like this, for example:
for name, c := range components.Components {
fmt.Println("Starting", name)
if err := c.Start(); err != nil {
return fmt.Errorf("failed to start components %s: %w", name, err)
}
}
this looks perfect thanks!! i will try this out right now
If you want to see a fully elaborated version of this pattern, I'll offer 2 such examples:
- From the standard library: database/sql (register: https://cs.opensource.google/go/go/+/refs/tags/go1.19.4:src/database/sql/sql.go;l=44)
- From open source: https://github.com/influxdata/telegraf (check for example the input plugin registry here: https://github.com/influxdata/telegraf/blob/master/plugins/inputs/registry.go and a registration here: https://github.com/influxdata/telegraf/blob/master/plugins/inputs/cpu/cpu.go#L166)