存储所有符合相同接口的类型的构造函数集合
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
我也试过了:
- 在没有指针的情况下赋值,虽然我在尝试时觉得很愚蠢
- 在
init
函数中有一个中间步骤,我将在其中创建一个 new(func (string) RulesEngine)
然后分配给它,有和没有指针。
- 像在 C 中一样存储函数指针,但编译器说它不能获取我的函数的地址。
我对 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)
显式转换也被编译器认为不合适)
我正在制作一个应用程序,它需要一组规则才能 运行 一份工作。该应用程序提供了用几种不同语言之一表达规则的可能性。因此,我定义了一个实时规则引擎的接口,它提供了应用程序查询当前规则集所需的方法。在这个界面的后面,根据源语言,会有一种不同类型的引擎。
现在我想根据规则文件的扩展名实例化一个规则引擎。但是我遇到了一些我很难克服的错误。
让我先提供这个简化的骨架:
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
来提供足够的构造函数,但是作为很有可能我想避免这种重复。
感谢您的任何见解!
(已编辑:我已经接受了我自己的答案,因为没有任何其他答案,但它最相关的部分是下面@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)
显式转换也被编译器认为不合适)