【问题标题】:Return a method from a Go closure从 Go 闭包返回一个方法
【发布时间】:2018-02-16 07:12:52
【问题描述】:

我希望能够为以下结构动态生成方法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 中是否可以实现这一点?

【问题讨论】:

    标签: go methods interface closures dispatch


    【解决方案1】:

    你不能在函数内部定义方法,详情见Golang nested class inside function

    您可以做的是创建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() 返回就足够了。但是该示例显示了如何在运行时选择将作为实现方法调用的函数。

    【讨论】:

    • 感谢伊扎!这太完美了——你也让我看到了一种在 Go 中抽象事物的新方法。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    • 2016-07-20
    相关资源
    最近更新 更多