I am trying to figure out a way to access struct from multiple packages with name.
Here is my structure:
collector/package1
collector/package2
.. package1 contains:
package collector
type NewRule struct {
}
.. package2 contains:
package collector
type OldRule struct {
}
....
In my main.go:
import "github.com/mypackage/collector"
sliceOfCollector := []string{"NewRule", "OldRule"}
for _, col := range sliceOfCollector{
// How to use the above collector name `col` to create struct instance.
}
Use reflect.New with struct
type. In Go you have to use type to create a new instance dynamically not string.
Example: To create struct instance dynamically, you can do
package main
import "reflect"
import (
"github.com/collector/package1"
"github.com/collector/package2"
)
func main() {
sliceOfCollector := make([]reflect.Type, 0)
sliceOfCollector = append(sliceOfCollector, reflect.TypeOf((*package1.NewRule)(nil)).Elem()})
sliceOfCollector = append(sliceOfCollector, reflect.TypeOf((*package2.OldRule)(nil)).Elem()})
for _, collectorType := range slice sliceOfCollector {
col := reflect.New(collectorType)
fmt.Printf("%#v
", col)
}
}
You can use type assertions after that col.Interface().(*package1.NewRule)
EDIT:
After comment interaction, added following.
Creating a instance using factory method. Just an idea.
func main() {
sliceOfCollector := []string{"NewRule", "OldRule"}
for _, col := range sliceOfCollector {
rule := CreateRuleByName(col)
fmt.Printf("%#v
", rule)
}
}
func CreateRuleByName(name string) interface{} {
switch name {
case "NewRule":
return &package1.NewRule{}
case "OldRule":
return &package2.OldRule{}
default:
return nil
}
}