存储所有符合相同接口的类型的构造函数集合

Store a collection of constructors for types that all conform to the same interface

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

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

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

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

我也试过了:

我对 Go 不太熟悉,这让我感到有点惊讶。什么是正确的类型签名使用?这可能吗?如果这是不可避免的,我显然会在一侧有一个简单的扩展数组(以检查文件是否可能是规则文件),在另一侧有一个大的 switch 来提供足够的构造函数,但是作为很有可能我想避免这种重复。

感谢您的任何见解!

(已编辑:我已经接受了我自己的答案,因为没有任何其他答案,但它最相关的部分是下面@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) 显式转换也被编译器认为不合适)