Return 来自 Go 闭包的方法

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 type> {
    return func (t *SomeCustomSObject) ApiName() string {
            return name
        }
} 

我知道上面的代码行不通,但是有没有办法在 Go 中实现这个?

您不能在函数内部定义方法,有关详细信息,请参阅

您可以做的是创建 SObject 的实现,它能够在其自己的实现中分派自定义函数。创建这样的 "proxy" 实现的一种简单方法是使用具有与方法类型匹配的函数类型字段的结构(没有接收器),并在此结构上实现方法。方法实现可以简单地将调用转发到存储在结构字段中的函数值,并且如果未设置适当的字段,则可能具有默认行为。并且您可以更改函数字段的值,方法的行为将是动态的。

这是一个例子:

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 函数字段可以完全省略,只存储来自 [=16] 的 name 和 return 就足够了=].但该示例显示了如何在运行时选择将作为实现方法调用的函数。