我正在制作一个需要一组规则来运行作业的应用程序。该应用程序提供了以几种不同语言之一来表达规则的可能性。因此,我已经定义了实时规则引擎的接口,该接口提供了该应用需要查询当前规则集的方法。在此界面后面,根据源语言将有一种不同类型的引擎。
现在,我想根据规则文件的扩展名实例化规则引擎。但是我得到了一些我很难克服的错误。
让我首先提供这个简化的骨架:
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)
明确施放的尝试也不适合)