存储一个符合同一接口的类型的构造函数集合



我正在制作一个需要一组规则来运行作业的应用程序。该应用程序提供了以几种不同语言之一来表达规则的可能性。因此,我已经定义了实时规则引擎的接口,该接口提供了该应用需要查询当前规则集的方法。在此界面后面,根据源语言将有一种不同类型的引擎。

现在,我想根据规则文件的扩展名实例化规则引擎。但是我得到了一些我很难克服的错误。

让我首先提供这个简化的骨架:

package main
//
//
// The interface
type RulesEngine interface {
    SomeRuleEvaluator(string) bool
}
//
//
// An implementation, with its constructor
type ASimpleRulesEngine struct {
    // I've also tried with :
    // RulesEngine
}
func NewASimpleRulesEngine(context string) *ASimpleRulesEngine {
    re := ASimpleRulesEngine{}
    return &re
}
func (re *ASimpleRulesEngine) SomeRuleEvaluator(dummy string) bool {
    return true
}
//
//
// A client, that'll want to be able to choose a constructor
var rulesEngineConstructorsPerExtension map[string](func(string) RulesEngine)
func init() {
    rulesEngineConstructorsPerExtension = make(map[string](func(string)RulesEngine))
    rulesEngineConstructorsPerExtension[".ini"] = NewASimpleRulesEngine
}
func main() {
}

当我尝试构建这个时,我会得到35: cannot use NewASimpleRulesEngine (type func(string) *ASimpleRulesEngine) as type func(string) RulesEngine in assignment

我也尝试了:

  • 分配没有指针,尽管我在尝试时感到很愚蠢
  • init函数中具有中间步骤,我将创建一个new(func (string) RulesEngine),然后在没有指针的情况下分配给它。
  • 像C中一样存储功能指针,但编译器说它不能接受我的功能的敬意。

我对GO并不熟悉,这有点令人惊讶。适当使用的签名是什么?这根本可能吗?如果不可避免,我显然在一侧有一系列简单的扩展名(检查文件是否可能是规则文件),另一侧是一个大的switch,以提供足够的构造函数,但我尽可能多地提供我'd喜欢避免这种重复。

谢谢您的任何见解!

(编辑:我已经因为缺乏其他任何内容而接受了自己的答案,但最相关的部分是@Seh的评论)


遵循@JorgeMarey的评论,不想牺牲构造函数的签名,我想出了这一点。但这对我来说确实很俗气。我很高兴听到更清洁的方式。

func init() {
    rulesEngineConstructorsPerExtension = make(map[string](func(string)RulesEngine))
    cast_NewASimpleRulesEngine := func(content string) RulesEngine {
        return NewASimpleRulesEngine(content)
    }
    rulesEngineConstructorsPerExtension[".ini"] = cast_NewASimpleRulesEngine
}

(编译器也认为与(func(string)RulesEngine)( NewASimpleRulesEngine)明确施放的尝试也不适合)

最新更新