英文:
Return a method from a Go closure
问题
我想要能够动态生成一个方法ApiName
,用于以下结构体:
type SomeCustomSObject struct {
sobjects.BaseSObject
}
我想要为以下接口实现该方法:
type SObject interface {
ApiName() string
ExternalIdApiName() string
}
我希望能够按照以下方式动态创建该方法:
func createApiNameMethod(name string) <返回类型> {
return func(t *SomeCustomSObject) string {
return name
}
}
我知道上面的代码不起作用,但在Go语言中有没有实现这个目标的方法呢?
英文:
I want to be able to dynamically generate a method ApiName
for the following struct:
type SomeCustomSObject struct {
sobjects.BaseSObject
}
The interface I want to implement the method for is as follows:
type SObject interface {
ApiName() string
ExternalIdApiName() string
}
I would like to dynamically create the method as follows:
func createApiNameMethod(name, string) <return type> {
return func (t *SomeCustomSObject) ApiName() string {
return name
}
}
I know the code above does not work, but is there anyway to acheive this in Go?
答案1
得分: 4
你不能在函数内部定义方法,详细信息请参见https://stackoverflow.com/questions/28252117/golang-nested-class-inside-function/28252170#28252170。
你可以创建一个SObject
的实现,该实现能够在自己的实现中调用自定义函数。创建这样一个“代理”实现的简单方法是使用一个结构体,其字段是函数类型,与方法的类型匹配(没有接收者),并在该结构体上实现方法。方法的实现可以简单地将调用转发到存储在结构体字段中的函数值,并且如果适当的字段未设置,则可以具有默认行为。你可以更改函数字段的值,方法的行为将是动态的。
这是一个示例:
type sobjimpl struct {
apiName func() string
externalIdApiName func() string
}
func (s *sobjimpl) ApiName() string {
if s.apiName == nil {
return "<not implemented>"
}
return s.apiName()
}
func (s *sobjimpl) ExternalIdApiName() string {
if s.externalIdApiName == nil {
return "<not implemented>"
}
return s.externalIdApiName()
}
func createApiNameMethod(name string) SObject {
return &sobjimpl{
apiName: func() string { return name },
}
}
测试它:
so := createApiNameMethod("testName")
fmt.Println(so.ApiName())
输出结果如预期(在Go Playground上尝试):
testName
当然,在这个简单的示例中,sobjimpl.apiName
函数字段可以完全省略,只需存储name
并从sobjimpl.ApiName()
返回即可。但是该示例展示了如何在运行时选择将作为实现方法调用的函数。
英文:
You can't define methods inside a function, for details see https://stackoverflow.com/questions/28252117/golang-nested-class-inside-function/28252170#28252170.
What you may do is create an implementation of SObject
which is capable of dispatching to custom functions in its own implementation. An easy way to create such "proxy" implementation is to use a struct with fields of function types matching the types of the methods (without a receiver), and implement methods on this struct. The method implementations may simply forward the calls to the function values stored in the struct fields, and may have a default behavior if the appropriate field is not set. And you may change the values of the function fields, the behavior of the methods will be dynamic.
Here's an example of it:
type sobjimpl struct {
apiName func() string
externalIdApiName func() string
}
func (s *sobjimpl) ApiName() string {
if s.apiName == nil {
return "<not implemented>"
}
return s.apiName()
}
func (s *sobjimpl) ExternalIdApiName() string {
if s.externalIdApiName == nil {
return "<not implemented>"
}
return s.externalIdApiName()
}
func createApiNameMethod(name string) SObject {
return &sobjimpl{
apiName: func() string { return name },
}
}
Testing it:
so := createApiNameMethod("testName")
fmt.Println(so.ApiName())
Output is as expected (try it on the Go Playground):
testName
Of course in this simple example the sobjimpl.apiName
function field could be left out entirely, it could have been enough to just store the name
and return that from sobjimpl.ApiName()
. But the example shows how you may choose functions at runtime that will be called as the methods of an implementation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论