doudeng2016 2014-10-06 18:26
浏览 57
已采纳

如何在interface {}变量上进行类型断言以测试其是否为函数?

I am attempting to write a function that accepts either some type of content of arbitrary type or a function that can generate and return an arbitrary type. To do this, I have to be able to generally test if an argument is a function without testing for whether it is a function of return type X. How do I do this? Might look something like the following:

func Blah(arbitrary interface{}) {
    var value interface{}

    if function, ok := arbitrary.(func interface{}); ok {
        value = function()
    } else {
        value = arbitrary
    }
    ...
}

This fails as is. Maybe a type assertion isn't the thing to use here. Or maybe I just don't know the syntax. Would appreciate any suggestions. Only thing I know to do at present is to divide this up into two functions, one that accepts data to be stored as is, and another that expects to get a function, but that seems overkill when in both cases the goal is simply to get a value and pass it on to the rest of the function.

Any ideas on this?

  • 写回答

1条回答 默认 最新

  • dqmnueuu459279 2014-10-06 18:34
    关注

    Type assertions work on specific types. If you know that the type of the function always has type func() interface{}, then you can use:

    if f, ok := arbitrary.(func() interface{}) {
        value = f()
    } else {
        value = arbitrary
    }
    

    Note that the type func() interface{} is a function with return type interface{}, not a function with an arbitrary return type.

    It's easy to wrap an arbitrary function to a func() interface{}:

    func hello() string { return "hello" }
    
    wrapped := func() interface{} { return hello() }
    

    If you cannot arrange for the function to have return type interface{}, then you need to use reflection to test and call the function:

    func isFunction(v interface{}) (func() interface{}, bool) {
      rv := reflect.ValueOf(v)
      if rv.Kind() == reflect.Func {
        return func() interface{} {
            result := rv.Call(nil)
            if len(result) > 0 {
                return result[0].Interface()
            }
            return nil
        }, true
      }
    
      return nil, false
    }
    
    ---
    
    if f, ok := isFunction(arbitrary); ok {
        value = f
    } else {
        value = arbitrary
    }
    

    <kbd>playground</kbd>

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

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端