从Go闭包返回一个方法

时间:2017-09-07 13:52:08

标签: go methods interface closures dispatch

我希望能够为以下结构动态生成方法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
        }
} 

我想动态创建方法如下:

std::cout

我知道上面的代码不起作用,但无论如何都要在Go中实现这一点吗?

1 个答案:

答案 0 :(得分:3)

您无法在函数内定义方法,有关详细信息,请参阅Golang nested class inside function

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

以下是它的一个例子:

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()返回即可。但该示例显示了如何在运行时选择将被称为实现方法的函数。