包含字符串名称的包选择器

时间:2017-07-12 22:42:41

标签: go struct

我试图想出一种从多个包名称访问struct的方法。

这是我的结构:

collector/package1
collector/package2

.. package1包含:

package collector

type NewRule struct {
}

.. package2包含:

package collector

type OldRule struct {
}

...

在我的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.
 }

1 个答案:

答案 0 :(得分:3)

reflect.Newstruct类型一起使用。在Go中,您必须使用type来动态创建新实例而不是字符串。

示例:要动态创建结构实例,可以执行

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\n", col)
    }
}

您可以在col.Interface().(*package1.NewRule)

之后使用type assertions

修改

评论互动后,添加了以下内容。

使用工厂方法创建实例。只是一个想法。

func main() {
    sliceOfCollector := []string{"NewRule", "OldRule"}

    for _, col := range sliceOfCollector {
        rule := CreateRuleByName(col)
        fmt.Printf("%#v\n", rule)
    }
}

func CreateRuleByName(name string) interface{} {
    switch name {
    case "NewRule":
       return &package1.NewRule{}
    case "OldRule":
       return &package2.OldRule{}
    default:
       return nil
    }
}