简体   繁体   English

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

[英]How do I do a type assertion on an interface{} variable to test if it is a function?

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? 为此,我必须能够通常测试一个参数是否是一个函数,而无需测试它是否是返回类型X的函数。我该怎么做? 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? 有什么想法吗?

Type assertions work on specific types. 类型断言适用于特定类型。 If you know that the type of the function always has type func() interface{} , then you can use: 如果您知道函数的类型始终具有func() interface{} ,则可以使用:

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. 请注意,类型func() interface{}是具有返回类型interface{}的函数,而不是具有任意返回类型的函数。

It's easy to wrap an arbitrary function to a func() interface{} : 将任意函数包装到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: 如果您不能安排该函数具有返回类型interface{} ,则需要使用反射来测试并调用该函数:

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
}

playground 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将jquery中的变量发送到回调函数? 函数(r){} - How do I send a variable in jquery to a callback function? function(r){ } 如何传递可变数量的参数以及回调函数? - How do I pass a variable number of parameters along with a callback function? 如何调用存储在深度不确定的变量中的函数 - How do I call a function stored in a variable that is of indeterminate depth 如何使用uicontrol回调函数更改变量? - How do I alter a variable with a uicontrol callback function? 如何将变量传递给回调函数? - How do you pass variable to callback function? 如何更改此类的变量 - How do I change the variable of this class Java - 接口 - 如何在多个活动中一起分配特定接口 - Java - Interface - How do I assign a specific interface in multiple activities all together 如何分配给 std::function 类型的成员<bool(wxstring&)></bool(wxstring&)> - How do I assign to member of type std::function<bool(wxString&)> 事务处理后如何在Laravel中执行回调函数 - How do I do a callback function in Laravel after a transaction processes 我该如何回调此Objective-C函数的结果? - How do I do a callback of the result of this objective-c function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM