doudao8283 2017-09-07 13:52
浏览 68
已采纳

从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条回答 默认 最新

  • dongpo8702 2017-09-07 14:20
    关注

    You can't define methods inside a function, for details see Golang nested class inside function.

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算